<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  

  
  <title>Abel&#39;Blog</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta property="og:type" content="website">
<meta property="og:title" content="Abel&#39;Blog">
<meta property="og:url" content="http://example.com/page/4/index.html">
<meta property="og:site_name" content="Abel&#39;Blog">
<meta property="og:locale" content="en_US">
<meta property="article:author" content="Abel Sean">
<meta name="twitter:card" content="summary">
  
    <link rel="alternate" href="/atom.xml" title="Abel&#39;Blog" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  
<link rel="stylesheet" href="/css/style.css">

<meta name="generator" content="Hexo 5.4.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">Abel&#39;Blog</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://example.com"></form>
      </div>
    </div>
  </div>
</header>
      <div class="outer">
        <section id="main">
  
    <article id="post-2020/2020-11-12-bash" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/11/12/2020/2020-11-12-bash/" class="article-date">
  <time datetime="2020-11-11T16:00:00.000Z" itemprop="datePublished">2020-11-12</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/11/12/2020/2020-11-12-bash/">Linux-bash</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>记录一下Linux运维的时候常用的bash的知识</p>
<h1 id="目录相关"><a href="#目录相关" class="headerlink" title="目录相关"></a>目录相关</h1><h2 id="获取当前文件的绝对目录"><a href="#获取当前文件的绝对目录" class="headerlink" title="获取当前文件的绝对目录"></a>获取当前文件的绝对目录</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> [ -L <span class="variable">$0</span> ]</span><br><span class="line"><span class="keyword">then</span></span><br><span class="line">    BASE_DIR=`dirname $(readlink <span class="variable">$0</span>)`</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">    BASE_DIR=`dirname <span class="variable">$0</span>`</span><br><span class="line"><span class="keyword">fi</span></span><br></pre></td></tr></table></figure>

<p>$0 获取当前可执行程序的名称；</p>
<p>if [ -L $0 ] 用于检查一个名字是否为link；</p>
<p>$(readlink $0) 用于获取一个文件的正式的位置；</p>
<p>dirname 直接获取某个文件所在目录</p>
<h1 id="本地IP地址抓取"><a href="#本地IP地址抓取" class="headerlink" title="本地IP地址抓取"></a>本地IP地址抓取</h1><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">LOCALIP=`ip addr|grep <span class="string">&quot;eth0:&quot;</span> -A 3|grep <span class="string">&quot;inet &quot;</span>|sed -r <span class="string">&quot;s@.* (([0-9]&#123;1,3&#125;\.)&#123;3&#125;[0-9]&#123;1,3&#125;)/(32|24|16|8) .*@\1@&quot;</span>`</span><br></pre></td></tr></table></figure>

<p>中间是使用了 s@正则@\1@ 来抓取了其中的IP地址；</p>
<h1 id="if语句"><a href="#if语句" class="headerlink" title="if语句"></a>if语句</h1><table>
<thead>
<tr>
<th align="left">指令</th>
<th align="left">备注</th>
</tr>
</thead>
<tbody><tr>
<td align="left">–b</td>
<td align="left">当file存在并且是块文件时返回真</td>
</tr>
<tr>
<td align="left">-c</td>
<td align="left">当file存在并且是字符文件时返回真</td>
</tr>
<tr>
<td align="left">-d</td>
<td align="left">当pathname存在并且是一个目录时返回真</td>
</tr>
<tr>
<td align="left">-e</td>
<td align="left">当pathname指定的文件或目录存在时返回真</td>
</tr>
<tr>
<td align="left">-f</td>
<td align="left">当file存在并且是正规文件时返回真</td>
</tr>
<tr>
<td align="left">-g</td>
<td align="left">当由pathname指定的文件或目录存在并且设置了SGID位时返回为真</td>
</tr>
<tr>
<td align="left">-h</td>
<td align="left">当file存在并且是符号链接文件时返回真，该选项在一些老系统上无效</td>
</tr>
<tr>
<td align="left">-k</td>
<td align="left">当由pathname指定的文件或目录存在并且设置了“粘滞”位时返回真</td>
</tr>
<tr>
<td align="left">-p</td>
<td align="left">当file存在并且是命令管道时返回为真</td>
</tr>
<tr>
<td align="left">-r</td>
<td align="left">当由pathname指定的文件或目录存在并且可读时返回为真</td>
</tr>
<tr>
<td align="left">-s</td>
<td align="left">当file存在文件大小大于0时返回真</td>
</tr>
<tr>
<td align="left">-u</td>
<td align="left">当由pathname指定的文件或目录存在并且设置了SUID位时返回真</td>
</tr>
<tr>
<td align="left">-w</td>
<td align="left">当由pathname指定的文件或目录存在并且可执行时返回真。一个目录为了它的内容被访问必然是可执行的。</td>
</tr>
<tr>
<td align="left">-o</td>
<td align="left">当由pathname指定的文件或目录存在并且被子当前进程的有效用户ID所指定的用户拥有时返回真。</td>
</tr>
</tbody></table>
<h1 id="字符串、数字比较"><a href="#字符串、数字比较" class="headerlink" title="字符串、数字比较"></a>字符串、数字比较</h1><table>
<thead>
<tr>
<th align="left">运算符</th>
<th align="left">描述</th>
<th align="left">示例</th>
</tr>
</thead>
<tbody><tr>
<td align="left">-e filename</td>
<td align="left">如果 filename 存在，则为真</td>
<td align="left">[ -e /var/log/syslog ]</td>
</tr>
<tr>
<td align="left">-d filename</td>
<td align="left">如果 filename 为目录，则为真</td>
<td align="left">[ -d /tmp/mydir ]</td>
</tr>
<tr>
<td align="left">-f filename</td>
<td align="left">如果 filename 为常规文件，则为真</td>
<td align="left">[ -f /usr/bin/grep ]</td>
</tr>
<tr>
<td align="left">-L filename</td>
<td align="left">如果 filename 为符号链接，则为真</td>
<td align="left">[ -L /usr/bin/grep ]</td>
</tr>
<tr>
<td align="left">-r filename</td>
<td align="left">如果 filename 可读，则为真</td>
<td align="left">[ -r /var/log/syslog ]</td>
</tr>
<tr>
<td align="left">-w filename</td>
<td align="left">如果 filename 可写，则为真</td>
<td align="left">[ -w /var/mytmp.txt ]</td>
</tr>
<tr>
<td align="left">-x filename</td>
<td align="left">如果 filename 可执行，则为真</td>
<td align="left">[ -L /usr/bin/grep ]</td>
</tr>
<tr>
<td align="left">-z string</td>
<td align="left">如果 string 长度为零，则为真</td>
<td align="left">[ -z $myvar ]</td>
</tr>
<tr>
<td align="left">-n string</td>
<td align="left">如果 string 长度非零，则为真</td>
<td align="left">[ -n $myvar ]</td>
</tr>
<tr>
<td align="left">string1 = string2</td>
<td align="left">如果 string1 与 string2 相同，则为真</td>
<td align="left">[ $myvar = one two three ]</td>
</tr>
<tr>
<td align="left">string1 != string2</td>
<td align="left">如果 string1 与 string2 不同，则为真</td>
<td align="left">[ $myvar != one two three ]</td>
</tr>
<tr>
<td align="left">num1 -eq num2</td>
<td align="left">等于</td>
<td align="left">[ 3 -eq $mynum ]</td>
</tr>
<tr>
<td align="left">num1 -ne num2</td>
<td align="left">不等于</td>
<td align="left">[ 3 -ne $mynum ]</td>
</tr>
<tr>
<td align="left">num1 -lt num2</td>
<td align="left">小于</td>
<td align="left">[ 3 -lt $mynum ]</td>
</tr>
<tr>
<td align="left">num1 -le num2</td>
<td align="left">小于或等于</td>
<td align="left">[ 3 -le $mynum ]</td>
</tr>
<tr>
<td align="left">num1 -gt num2</td>
<td align="left">大于</td>
<td align="left">[ 3 -gt $mynum ]</td>
</tr>
<tr>
<td align="left">num1 -ge num2</td>
<td align="left">大于或等于</td>
<td align="left">[ 3 -ge $mynum ]</td>
</tr>
</tbody></table>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">　　filename1 -nt filename2 如果 filename1 比 filename2 新，则为真 [ /tmp/install/etc/services -nt /etc/services ]</span><br><span class="line">　　filename1 -ot filename2   如果 filename1 比 filename2 旧，则为真  [ /boot/bzImage -ot arch/i386/boot/bzImage ]</span><br></pre></td></tr></table></figure>

<h1 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h1><ul>
<li>[1] <a target="_blank" rel="noopener" href="https://www.cnblogs.com/image-eye/archive/2011/08/20/2147015.html">Linux中使用的if语句</a></li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://example.com/2020/11/12/2020/2020-11-12-bash/" data-id="ckrn3an71000l20xw3yr69kvr" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Linux/" rel="tag">Linux</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-2020/2020-11-10-linux-env-init" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/11/10/2020/2020-11-10-linux-env-init/" class="article-date">
  <time datetime="2020-11-09T16:00:00.000Z" itemprop="datePublished">2020-11-10</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/11/10/2020/2020-11-10-linux-env-init/">Linux-环境配置</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <ul>
<li><a href="#centos">Centos</a><ul>
<li><a href="#centos-7%E9%98%B2%E7%81%AB%E5%A2%99">centos 7防火墙</a><ul>
<li><a href="#%E6%A3%80%E6%9F%A5%E9%98%B2%E7%81%AB%E5%A2%99%E7%8A%B6%E6%80%81">检查防火墙状态</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#ubuntu">ubuntu</a><ul>
<li><a href="#apt-%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86">apt 相关知识</a></li>
</ul>
</li>
<li><a href="#mysql">mysql</a><ul>
<li><a href="#%E6%9D%83%E9%99%90%E7%9B%B8%E5%85%B3">权限相关</a></li>
<li><a href="#%E5%A4%87%E4%BB%BD%E6%95%B0%E6%8D%AE%E5%BA%93">备份数据库</a></li>
</ul>
</li>
<li><a href="#cygwin%E5%A4%9A%E6%AC%A1grep%E6%B2%A1%E6%9C%89%E8%BE%93%E5%87%BA">cygwin多次grep没有输出</a></li>
<li><a href="#ubuntu%E6%97%A0%E6%B3%95%E6%9B%B4%E6%96%B0">ubuntu无法更新</a></li>
<li><a href="#wsl">WSL</a></li>
<li><a href="#%E5%BC%95%E7%94%A8">引用</a></li>
</ul>
<p>记录一下Linux运维相关的学习资料；</p>
<h1 id="Centos"><a href="#Centos" class="headerlink" title="Centos"></a>Centos</h1><p>安装完，可以直接将<code>/etc/sysconfig/network-scripts/ifcfg-xxx</code>此选项打开<code>ONBOOT=yes</code>。这样一般都能上网了。</p>
<p>EPEL (Extra Packages for Enterprise Linux)是基于Fedora的一个项目，为“红帽系”的操作系统提供额外的软件包，适用于RHEL、CentOS和Scientific Linux.如果不安装这个库，将会少了很多的软件包。<code>yum -y install epel-release</code></p>
<p>可以安装一下<code>zsh</code>，<code>autojump</code>，<code>autojump-zsh</code>，<code>oh-my-zsh</code>。自从2019年之后，<code>mac</code>就默认使用<code>zsh</code>代替了<code>bash</code>。</p>
<p><code>git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh</code></p>
<p>安装了<code>zsh</code>之后，可以通过执行<code>chsh</code>来设置成默认的shell。安装完成之后xshell工具的home键无法使用。可以通过在zshrc文件里面添加这些内容</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">bindkey</span> <span class="string">&#x27;\e[1~&#x27;</span> beginning-of-line</span><br><span class="line"><span class="built_in">bindkey</span> <span class="string">&#x27;\e[4~&#x27;</span> end-of-line</span><br></pre></td></tr></table></figure>

<p>参考文档<a target="_blank" rel="noopener" href="https://stackoverflow.com/questions/161676/home-end-keys-in-zsh-dont-work-with-putty">home-end-keys-in-zsh-dont-work-with-putty</a></p>
<p>有时候会升级失败，这个还是由于git访问不流畅造成。</p>
<ol>
<li>先将本地的oh my zsh目录找到，通过git pull直接拉取最新的版本；</li>
<li>执行这个指令 upgrade_oh_my_zsh 就能将版本升级好了。</li>
</ol>
<p>常用的软件：</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">yum install -y wget git screen libtool automake</span><br><span class="line">yum install zlib-devel -y</span><br><span class="line">yum install centos-release-scl</span><br><span class="line">yum makecache</span><br><span class="line">yum install devtoolset-7-gcc-c++ -y</span><br><span class="line">yum install llvm-toolset-7 -y</span><br><span class="line">yum install cmake -y</span><br><span class="line">yum install python3-devel</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装man</span></span><br><span class="line">yum install man-pages man-db man</span><br><span class="line"></span><br><span class="line"><span class="comment"># c++ 帮助文件</span></span><br><span class="line">yum install man-pages libstdc++-docs</span><br><span class="line"></span><br><span class="line"><span class="comment"># 网路分析工具</span></span><br><span class="line">yum install tcpdump</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装gcc调试信息</span></span><br><span class="line">debuginfo-install gcc</span><br><span class="line"><span class="comment"># 最后能切换gcc版本：</span></span><br><span class="line">scl <span class="built_in">enable</span> llvm-toolset-7 devtoolset-7 bash</span><br><span class="line">curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py</span><br><span class="line">python get-pip.py</span><br><span class="line">pip install shadowsocks</span><br><span class="line">mariadb-libs</span><br><span class="line">mariadb-devel</span><br><span class="line">yum install mariadb-server</span><br><span class="line">systemctl start mariadb</span><br><span class="line">systemctl <span class="built_in">enable</span> mariadb</span><br><span class="line"></span><br><span class="line"><span class="comment"># 通过命令查看版本</span></span><br><span class="line">yum info cmake</span><br><span class="line"></span><br><span class="line"><span class="comment"># 切换脚本，如果不想用了，可以将这个从</span></span><br><span class="line">/etc/bashrc/profile</span><br><span class="line"><span class="comment"># 文件</span></span><br><span class="line"><span class="built_in">source</span> /opt/rh/llvm-toolset-7/<span class="built_in">enable</span></span><br><span class="line"><span class="built_in">source</span> /opt/rh/devtoolset-7/<span class="built_in">enable</span></span><br></pre></td></tr></table></figure>

<p>man帮助文件的章节意义</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">The section numbers of the manual pages are as follows:</span><br><span class="line"></span><br><span class="line">    1 – Executable programs or shell commands</span><br><span class="line">    2 – System calls (functions provided by the kernel)</span><br><span class="line">    3 – Library calls (functions within program libraries)</span><br><span class="line">    4 – Special files (usually found in /dev)</span><br><span class="line">    5 – File formats and conventions eg /etc/passwd</span><br><span class="line">    6 – Games</span><br><span class="line">    7 – Miscellaneous (including macro packages and conventions), e.g. man(7), groff(7)</span><br><span class="line">    8 – System administration commands (usually only for root)</span><br><span class="line">    9 – Kernel routines [Non standard]</span><br></pre></td></tr></table></figure>

<h2 id="centos-7防火墙"><a href="#centos-7防火墙" class="headerlink" title="centos 7防火墙"></a>centos 7防火墙</h2><h3 id="检查防火墙状态"><a href="#检查防火墙状态" class="headerlink" title="检查防火墙状态"></a>检查防火墙状态</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">firewall-cmd --list-all</span><br><span class="line">firewall-cmd --state</span><br></pre></td></tr></table></figure>

<p>禁用随系统启动防火墙</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl disable firewalld</span><br></pre></td></tr></table></figure>

<p>启用随系统启动防火墙</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl enable firewalld</span><br></pre></td></tr></table></figure>

<p>关闭防火墙</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl stop firewalld</span><br></pre></td></tr></table></figure>

<p>当前防火墙服务状态</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl status firewalld</span><br></pre></td></tr></table></figure>

<p>永久开放防火墙端口</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">firewall-cmd --permanent --zone=public --add-port=52310-52320/tcp </span><br><span class="line">sudo firewall-cmd --zone=public --add-port=3000/tcp --permanent</span><br></pre></td></tr></table></figure>

<p>重新加载防火墙规则</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo firewall-cmd --reload</span><br></pre></td></tr></table></figure>

<p>netcat 尝试端口连接</p>
<p>使用tcp4方式连接一个ip地址的端口</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">nc -4 ip_address port</span><br><span class="line">nc --help</span><br><span class="line">See the ncat(1) manpage for full options, descriptions and usage examples</span><br><span class="line">man ncat</span><br><span class="line">Ncat 7.50 ( https://nmap.org/ncat )</span><br></pre></td></tr></table></figure>

<p>在帮助文件里面可以获取更多的信息。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Connect to example.org on TCP port 8080.</span><br><span class="line">    ncat example.org 8080</span><br><span class="line"></span><br><span class="line">Listen for connections on TCP port 8080.</span><br><span class="line">    ncat -l 8080</span><br></pre></td></tr></table></figure>

<p>检查端口情况</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">netstat -tnlp</span><br><span class="line">``</span><br><span class="line"></span><br><span class="line">检查当前</span><br><span class="line"></span><br><span class="line"># Linux系统设置</span><br><span class="line"></span><br><span class="line"># 修改时区</span><br><span class="line"></span><br><span class="line">cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime</span><br><span class="line"></span><br><span class="line">locale设置</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>[root@vm10-0-2-2 raw_database]# locale<br>LANG=en_US.UTF-8<br>LC_CTYPE=”en_US.UTF-8”<br>LC_NUMERIC=”en_US.UTF-8”<br>LC_TIME=”en_US.UTF-8”<br>LC_COLLATE=”en_US.UTF-8”<br>LC_MONETARY=”en_US.UTF-8”<br>LC_MESSAGES=”en_US.UTF-8”<br>LC_PAPER=”en_US.UTF-8”<br>LC_NAME=”en_US.UTF-8”<br>LC_ADDRESS=”en_US.UTF-8”<br>LC_TELEPHONE=”en_US.UTF-8”<br>LC_MEASUREMENT=”en_US.UTF-8”<br>LC_IDENTIFICATION=”en_US.UTF-8”<br>LC_ALL=</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">如果发现有问题，可以通过在/etc/profile文件中添加</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>export LANG=”en_US.UTF-8”<br>export LC_ALL=”en_US.UTF-8”</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">## 检查coredump的配置</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>cat /proc/sys/kernel/core_pattern</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">一般我们将coredump文件生成目录重定向到一个固定的地方：</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>mkdir -p /data/cores/<br>chmod a+w /data/cores/ -R<br>echo “/home/cores/core-%e-%p-%t” &gt; /proc/sys/kernel/core_pattern</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">设置ulimit</span><br><span class="line"></span><br><span class="line">```bash</span><br><span class="line">ulimit -n 65535  </span><br><span class="line">ulimit -c unlimited</span><br><span class="line"></span><br><span class="line"># 直接修改这个文件，在这个文件尾部放入3行</span><br><span class="line">vi /etc/security/limits.conf</span><br><span class="line"></span><br><span class="line">* soft nofile 65535</span><br><span class="line">* hard nofile 65535</span><br><span class="line">* soft core unlimited</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>centos yum proxy</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">/etc/yum.conf</span><br><span class="line">proxy=http://代理服务器IP地址:端口号</span><br><span class="line">proxy=http://代理服务器IP地址:端口号</span><br><span class="line">proxy_username=代理服务器用户名</span><br><span class="line">proxy_password=代理服务器密码</span><br></pre></td></tr></table></figure>

<p>centos安装python3.6</p>
<p>softwarecollections.org</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1. Install a package with repository for your system:</span></span><br><span class="line"><span class="comment"># On CentOS, install package centos-release-scl available in CentOS repository</span></span><br><span class="line"><span class="comment"># and enable the testing repository:</span></span><br><span class="line">$ sudo yum install centos-release-scl</span><br><span class="line">$ sudo yum-config-manager --<span class="built_in">enable</span> centos-sclo-rh-testing</span><br><span class="line"></span><br><span class="line"><span class="comment"># On RHEL, enable RHSCL and RHSCL-beta repositories for you system:</span></span><br><span class="line">$ sudo yum-config-manager --<span class="built_in">enable</span> rhel-server-rhscl-7-rpms</span><br><span class="line">$ sudo yum-config-manager --<span class="built_in">enable</span> rhel-server-rhscl-beta-7-rpms</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. Install the collection:</span></span><br><span class="line">$ sudo yum install rh-python36</span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. Start using software collections:</span></span><br><span class="line">$ scl <span class="built_in">enable</span> rh-python36 bash</span><br></pre></td></tr></table></figure>

<h1 id="ubuntu"><a href="#ubuntu" class="headerlink" title="ubuntu"></a>ubuntu</h1><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get update &amp;&amp; apt-get upgrade</span><br><span class="line">sudo apt-get install mariadb-server -y</span><br><span class="line">sudo apt-get install unzip -y</span><br><span class="line">sudo apt-get install zlib1g-dev -y</span><br><span class="line">sudo apt-get install libmariadbclient-dev -y</span><br><span class="line">sudo apt install p7zip-full -y</span><br><span class="line">sudo apt install -y <span class="string">&quot;screen&quot;</span></span><br><span class="line">sudo apt install clang-format -y</span><br><span class="line">sudo apt-get install gcc-7 g++-7 -y</span><br><span class="line">sudo apt-get install clang cmake unzip screen clang-format mariadb-server unzip golang python3-pip automake -y</span><br><span class="line">sudo apt-get install git libmariadbclient-dev p7zip-full openssl -y</span><br><span class="line">sudo apt-get install nodejs -y</span><br><span class="line">sudo apt-get install gdb -y</span><br><span class="line"></span><br><span class="line">apt update</span><br><span class="line">sudo apt update</span><br><span class="line">sudo apt upgrade</span><br><span class="line">sudo apt install build-essential -y</span><br><span class="line">sudo apt install ccache</span><br><span class="line">sudo apt install dos2unix</span><br><span class="line">apt -y install mariadb-server mariadb-client libmysqlclient-dev</span><br><span class="line">apt install libmysqlclient-dev</span><br><span class="line">apt install libcurl-dev</span><br><span class="line">apt install autoconf -y</span><br><span class="line">apt-get install manpages-dev glibc-doc libstdc++-10-doc</span><br><span class="line"></span><br><span class="line"><span class="comment"># libstdc++-10-doc This package contains documentation files for the GNU stdc++ library.</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># screen 无法使用的问题，其实就是重定向一下 screen 的工作目录就好了</span></span><br><span class="line">Cannot make directory <span class="string">&#x27;/run/screen&#x27;</span>: Permission denied</span><br><span class="line"><span class="built_in">export</span> SCREENDIR=<span class="variable">$HOME</span>/.screen</span><br><span class="line">abel@xiaozanbiao:~/learn/c++/octopus_svr/octopus_svr/build$ screen -S abel</span><br><span class="line">Directory /home/abel/.screen must have mode 700.</span><br><span class="line">abel@xiaozanbiao:~/learn/c++/octopus_svr/octopus_svr/build$ chmod 700 ~/.screen/</span><br><span class="line">abel@xiaozanbiao:~/learn/c++/octopus_svr/octopus_svr/build$ screen -S abel</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2020/12/18 添加一个命令，记录当前某个进程的cpu，内存情况；</span></span><br><span class="line">sudo apt install sysstat</span><br><span class="line"></span><br><span class="line"><span class="comment">#!/bin/bash</span></span><br><span class="line">prog_name=<span class="string">&quot;your_programe_name&quot;</span></span><br><span class="line">prog_mem=$(pidstat  -r -u -h -C <span class="variable">$prog_name</span> |awk <span class="string">&#x27;NR==4&#123;print $12&#125;&#x27;</span>)</span><br><span class="line">time=$(date <span class="string">&quot;+%Y-%m-%d %H:%M:%S&quot;</span>)</span><br><span class="line"><span class="built_in">echo</span> <span class="variable">$time</span><span class="string">&quot;\tmemory(Byte)\t&quot;</span><span class="variable">$prog_mem</span> &gt;&gt;~/record/prog_mem.log</span><br><span class="line"></span><br><span class="line"><span class="comment"># 抓取某个进程的内存使用情况；</span></span><br><span class="line"><span class="comment"># 每2秒钟检测一次，持续5秒</span></span><br><span class="line">$ pidstat -r -u -h -C Level 2 5</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># CentOS7 如何升级Git</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 启用Wandisco GIT存储库，在此之前我们先写入新yum存储库配置文件，在终端输入：</span></span><br><span class="line">vim /etc/yum.repos.d/wandisco-git.repo</span><br><span class="line"></span><br><span class="line">[wandisco-git]</span><br><span class="line">name=Wandisco GIT Repository</span><br><span class="line">baseurl=http://opensource.wandisco.com/centos/7/git/<span class="variable">$basearch</span>/</span><br><span class="line">enabled=1</span><br><span class="line">gpgcheck=1</span><br><span class="line">gpgkey=http://opensource.wandisco.com/RPM-GPG-KEY-WANdisco</span><br><span class="line"></span><br><span class="line"><span class="comment"># 导入存储库GPG密钥</span></span><br><span class="line">rpm --import http://opensource.wandisco.com/RPM-GPG-KEY-WANdisco</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装：</span></span><br><span class="line"></span><br><span class="line">yum install git</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装文档输出；</span></span><br><span class="line"></span><br><span class="line">sudo apt install graphviz</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="apt-相关知识"><a href="#apt-相关知识" class="headerlink" title="apt 相关知识"></a>apt 相关知识</h2><p><a target="_blank" rel="noopener" href="https://blog.csdn.net/yjk13703623757/article/details/78945576">使用apt-get查询安装指定版本的软件</a></p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">apt-cache show libjemalloc-dev</span><br><span class="line">Package: libjemalloc-dev</span><br><span class="line">Architecture: amd64</span><br><span class="line">Version: 5.2.1-1ubuntu1</span><br><span class="line">Priority: extra</span><br><span class="line">Section: universe/libdevel</span><br><span class="line">Source: jemalloc</span><br><span class="line">Origin: Ubuntu</span><br><span class="line">Maintainer: Ubuntu Developers &lt;ubuntu-devel-discuss@lists.ubuntu.com&gt;</span><br><span class="line">Original-Maintainer: Faidon Liambotis &lt;paravoid@debian.org&gt;</span><br><span class="line">Bugs: https://bugs.launchpad.net/ubuntu/+filebug</span><br><span class="line">Installed-Size: 2748</span><br><span class="line">Depends: libjemalloc2 (= 5.2.1-1ubuntu1)</span><br><span class="line">Suggests: binutils</span><br><span class="line">Filename: pool/universe/j/jemalloc/libjemalloc-dev_5.2.1-1ubuntu1_amd64.deb</span><br><span class="line">Size: 424588</span><br><span class="line">MD5sum: f519936da1e4557812ebad9cbf9e1029</span><br><span class="line">SHA1: 2e5e464c4c2f051b7f32ed44a805bd7f08ec3738</span><br><span class="line">SHA256: c5d64ba693ad45dd7c41f1d103a74816482601f7d0272ed49fc5441e9e1deb91</span><br><span class="line">Homepage: http://jemalloc.net/</span><br><span class="line">Description-en: development files and documentation <span class="keyword">for</span> jemalloc</span><br><span class="line"> Files used <span class="keyword">for</span> development with jemalloc. This package contains</span><br><span class="line"> headers and documentation.</span><br><span class="line"> .</span><br><span class="line"> jemalloc is a library providing a malloc(3) implementation <span class="keyword">for</span></span><br><span class="line"> multi-threaded processes on multi-processor systems.</span><br><span class="line">Description-md5: f91b42ea17991369b6b9cd46f2828e3f</span><br></pre></td></tr></table></figure>

<p>man 帮助文件安装</p>
<p><a target="_blank" rel="noopener" href="https://blog.csdn.net/aiwangtingyun/article/details/79273802">Linux下完整安装 manpages</a></p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install linux-doc </span><br><span class="line">sudo apt-get install libcorelinux-dev</span><br><span class="line">sudo apt-get install libstdc++-7-dev </span><br><span class="line">sudo apt-get install libstdc++-7-doc </span><br><span class="line">sudo apt-get install manpages* </span><br></pre></td></tr></table></figure>

<h1 id="mysql"><a href="#mysql" class="headerlink" title="mysql"></a>mysql</h1><h2 id="权限相关"><a href="#权限相关" class="headerlink" title="权限相关"></a>权限相关</h2><p>安装完成之后，需要做一些简单的处理，防止安全问题。mysql最后限制访问的ip地址，给指定的ip地址开放访问的独立的密码。</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">GRANT</span> <span class="keyword">ALL</span> PRIVILEGES <span class="keyword">ON</span> <span class="operator">*</span>.<span class="operator">*</span> <span class="keyword">TO</span> <span class="string">&#x27;root&#x27;</span>@<span class="string">&#x27;ip_address&#x27;</span> IDENTIFIED <span class="keyword">BY</span> <span class="string">&#x27;yourpassword&#x27;</span> <span class="keyword">WITH</span> <span class="keyword">GRANT</span> OPTION;</span><br><span class="line">FLUSH PRIVILEGES;</span><br></pre></td></tr></table></figure>

<p>使用这个命令将处理掉mysql的一些安全问题。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ mysql_secure_installation</span><br></pre></td></tr></table></figure>

<p>mysql 8.0 版本 root 密码修改</p>
<p>需要执行</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">flush privileges;</span><br></pre></td></tr></table></figure>

<p>然后再执行</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">ALTER user <span class="string">&#x27;root&#x27;</span>@<span class="string">&#x27;localhost&#x27;</span> IDENTIFIED BY <span class="string">&#x27;root&#x27;</span>;--修改密码为root</span><br><span class="line">create user <span class="keyword">if</span> not exists <span class="string">&#x27;root&#x27;</span>@<span class="string">&#x27;%&#x27;</span> identified by <span class="string">&#x27;123456&#x27;</span>;</span><br><span class="line">GRANT ALL ON gamedata005.* TO <span class="string">&#x27;root&#x27;</span>@<span class="string">&#x27;%&#x27;</span>;</span><br></pre></td></tr></table></figure>

<p><a target="_blank" rel="noopener" href="https://dev.mysql.com/doc/refman/8.0/en/">MySQL8.0手册</a></p>
<h2 id="备份数据库"><a href="#备份数据库" class="headerlink" title="备份数据库"></a>备份数据库</h2><p>将某个数据库导出，不需要导出数据</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ mysqldump --no-create-db=TRUE --no-data=TRUE -h<span class="string">&quot;ip_address&quot;</span> -uroot -pyourpassword gamedb_10001 &gt; gamedb_10001.sql</span><br></pre></td></tr></table></figure>

<p>具体参数可以通过mysqldump –help中看到。</p>
<p>直接创建数据库</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysql -h<span class="string">&quot;ip_address&quot;</span> -uroot -pyourpassword -e <span class="string">&quot;create database gamedb_30001&quot;</span></span><br></pre></td></tr></table></figure>

<p>将数据表创建到新库中</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysql -h<span class="string">&quot;ip_address&quot;</span> -uroot -pyourpassword gamedb_30001 &lt; gamedb_10001.sql</span><br></pre></td></tr></table></figure>

<h1 id="cygwin多次grep没有输出"><a href="#cygwin多次grep没有输出" class="headerlink" title="cygwin多次grep没有输出"></a>cygwin多次grep没有输出</h1><p>在.bashrc文件里面增加这一句：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">alias</span> grep=<span class="string">&#x27;grep --color --line-buffer&#x27;</span>                     <span class="comment"># show differences in colour</span></span><br></pre></td></tr></table></figure>

<p>发现grep失效，无法做正确输出。google研究了一下，原因如下：</p>
<p>管道 | 是全缓冲的，一般来说buffer_size为4096，有些是8192。不管具体值多少，只有buffer_size满了，才会看到输出。</p>
<p>在操作里  &gt;&gt;file 这个操作也是全缓冲的。调整如下</p>
<p>tail -f log | grep –line-buffer xxx | grep –line-buffer yyy</p>
<p>结果输出正常。</p>
<p>grep当带上了 –line-buffer 的时候，每输出一行，就刷新一次。</p>
<p>在unix里，块设备和普通文件，以及管道都是全缓冲的。</p>
<h1 id="ubuntu无法更新"><a href="#ubuntu无法更新" class="headerlink" title="ubuntu无法更新"></a>ubuntu无法更新</h1><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">The following packages have unmet dependencies</span><br></pre></td></tr></table></figure>

<p>后来我把阿里源换回Ubuntu原生的源就可以安装了，因为阿里源的包太新。<a target="_blank" rel="noopener" href="https://www.cnblogs.com/willaty/p/9522591.html">转载原文</a></p>
<h1 id="WSL"><a href="#WSL" class="headerlink" title="WSL"></a>WSL</h1><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># WSL-Ubuntu18.04 LTS 重启方法</span></span><br><span class="line"><span class="comment"># 以管理员权限运行cmd</span></span><br><span class="line">&gt;net stop LxssManager	//停止</span><br><span class="line">&gt;net <span class="built_in">start</span> LxssManager	//启动</span><br><span class="line"></span><br><span class="line"><span class="comment"># 将WSL搬家</span></span><br><span class="line"><span class="comment"># 首先查看所有分发版本</span></span><br><span class="line">&gt; wsl <span class="literal">-l</span> -<span class="literal">-all</span>  <span class="literal">-v</span></span><br><span class="line"><span class="comment"># 导出分发版为tar文件到d盘</span></span><br><span class="line">&gt; wsl -<span class="literal">-export</span> Ubuntu<span class="literal">-20</span>.<span class="number">04</span> d:\ubuntu20.<span class="number">04</span>.tar</span><br><span class="line"><span class="comment"># 注销当前分发版</span></span><br><span class="line">&gt; wsl -<span class="literal">-unregister</span> Ubuntu<span class="literal">-20</span>.<span class="number">04</span></span><br><span class="line"><span class="comment"># 重新导入并安装分发版在d:\ubuntu</span></span><br><span class="line">wsl -<span class="literal">-import</span> Ubuntu<span class="literal">-20</span>.<span class="number">04</span> d:\ubuntu d:\ubuntu20.<span class="number">04</span>.tar -<span class="literal">-version</span> <span class="number">2</span></span><br><span class="line"><span class="comment"># 设置默认登陆用户为安装时用户名</span></span><br><span class="line">ubuntu2004 config -<span class="literal">-default</span><span class="literal">-user</span> Username</span><br><span class="line"><span class="comment"># 删除tar文件(可选)</span></span><br><span class="line"><span class="built_in">del</span> d:\ubuntu20.<span class="number">04</span>.tar</span><br><span class="line"><span class="comment"># 这个操作，完成之后我的WSL也从1升级到2了。</span></span><br><span class="line"><span class="comment"># 升级了之后，WSL完全拥有独立的ip地址；</span></span><br></pre></td></tr></table></figure>

<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Linux找出全部可执行文件，并且删除掉。</span><br><span class="line">ls -F|grep <span class="string">&#x27;*&#x27;</span> | sed <span class="string">&#x27;s#*##g&#x27;</span> | xargs rm</span><br><span class="line">参考网站： https://www.cnblogs.com/binyue/p/4707948.html</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p><a target="_blank" rel="noopener" href="https://www.freesion.com/article/6352795169/">GPG生成</a></p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">We need to generate a lot of random bytes</span><br><span class="line"><span class="comment"># 通过 yum install rng-tools完成安装。</span></span><br><span class="line"><span class="comment"># 之后再执行命令：rngd -r /dev/urandom，生成**就能瞬间完成了。</span></span><br></pre></td></tr></table></figure>


<h1 id="引用"><a href="#引用" class="headerlink" title="引用"></a>引用</h1><ul>
<li>[1] <a target="_blank" rel="noopener" href="https://www.cnblogs.com/mrbug/p/12030777.html">CentOS7 如何升级Git</a></li>
<li>[2] <a target="_blank" rel="noopener" href="https://blog.csdn.net/weixin_33797791/article/details/89593991">多次grep没有输出</a></li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://example.com/2020/11/10/2020/2020-11-10-linux-env-init/" data-id="ckrn3an72000n20xw5mx43wia" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Linux/" rel="tag">Linux</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/%E8%BF%90%E7%BB%B4/" rel="tag">运维</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-2020/2020-11-04-learn_git" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/11/04/2020/2020-11-04-learn_git/" class="article-date">
  <time datetime="2020-11-03T16:00:00.000Z" itemprop="datePublished">2020-11-04</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/11/04/2020/2020-11-04-learn_git/">git学习</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <ul>
<li><a href="#%E5%AE%89%E8%A3%85">安装</a><ul>
<li><a href="#linux">Linux</a></li>
</ul>
</li>
<li><a href="#%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B">工作流程</a><ul>
<li><a href="#%E6%A6%82%E5%BF%B5">概念：</a></li>
<li><a href="#%E5%B7%A5%E4%BD%9C%E5%8C%BA%E6%93%8D%E4%BD%9C">工作区操作</a></li>
<li><a href="#%E8%BF%9C%E7%A8%8B%E6%93%8D%E4%BD%9C">远程操作</a><ul>
<li><a href="#%E5%88%86%E6%94%AF%E7%AE%A1%E7%90%86">分支管理</a></li>
<li><a href="#%E5%88%86%E6%94%AF%E5%90%88%E5%B9%B6">分支合并</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#git-%E4%BF%AE%E6%94%B9%E8%BF%9C%E7%A8%8B%E7%9A%84%E7%9B%AE%E5%BD%95">git 修改远程的目录</a></li>
<li><a href="#git%E8%BD%AC%E6%8D%A2%E6%8D%A2%E8%A1%8C%E7%AC%A6%E5%9B%9E%E8%BD%A6">git转换换行符（回车）</a></li>
<li><a href="#tags%E5%86%B2%E7%AA%81">tags冲突</a></li>
<li><a href="#%E5%8F%82%E8%80%83">参考</a></li>
</ul>
<p>学习git的笔记，将记录一下git如何使用。之前常用svn，现在转过来的时候，有些东西需要熟悉。将会持续更新此文档。</p>
<h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><h3 id="Linux"><a href="#Linux" class="headerlink" title="Linux"></a>Linux</h3><p>Ubuntu</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">$ apt-get install libcurl4-gnutls-dev libexpat1-dev gettext \</span><br><span class="line">  libz-dev libssl-dev</span><br><span class="line"></span><br><span class="line">$ apt-get install git</span><br><span class="line"></span><br><span class="line">$ git --version</span><br><span class="line">git version 1.8.1.2</span><br></pre></td></tr></table></figure>

<p>Centos/RedHat</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">$ yum install curl-devel expat-devel gettext-devel \</span><br><span class="line">  openssl-devel zlib-devel</span><br><span class="line"></span><br><span class="line">$ yum -y install git-core</span><br><span class="line"></span><br><span class="line">$ git --version</span><br><span class="line">git version 1.7.1</span><br></pre></td></tr></table></figure>

<p>设置自己的用户名</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ git config --global user.name <span class="string">&quot;Your Name&quot;</span></span><br><span class="line">$ git config --global user.email <span class="string">&quot;email@example.com&quot;</span></span><br></pre></td></tr></table></figure>

<p>Linux中记住密码的方式：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 在Linux里面记住密码的文件，这个文件需要创建在本工程目录之下，而不是在系统根目录下。</span></span><br><span class="line"><span class="comment"># http(s)://&#123;你的用户名&#125;:&#123;你的密码&#125;@你的服务器地址</span></span><br><span class="line"><span class="comment"># git config --global credential.helper store</span></span><br><span class="line">.git-credentials</span><br><span class="line"></span><br><span class="line"><span class="comment"># mac机器上保存密码</span></span><br><span class="line">git config --global credential.helper osxkeychain</span><br></pre></td></tr></table></figure>

<h2 id="工作流程"><a href="#工作流程" class="headerlink" title="工作流程"></a>工作流程</h2><h3 id="概念："><a href="#概念：" class="headerlink" title="概念："></a>概念：</h3><table>
<thead>
<tr>
<th align="left">名称</th>
<th align="left">说明</th>
</tr>
</thead>
<tbody><tr>
<td align="left">远程 Git 资源</td>
<td align="left">共享git版本的一个库</td>
</tr>
<tr>
<td align="left">工作区</td>
<td align="left">本地编辑</td>
</tr>
<tr>
<td align="left">暂存区</td>
<td align="left">本地修改了之后，可以将修改提交到本地</td>
</tr>
<tr>
<td align="left">推送</td>
<td align="left">将本地的内容推送到远程Git资源服</td>
</tr>
</tbody></table>
<p><a target="_blank" rel="noopener" href="https://imgchr.com/i/Bj6XOe"><img src="https://s1.ax1x.com/2020/11/11/Bj6XOe.jpg" alt="Bj6XOe.jpg"></a></p>
<h3 id="工作区操作"><a href="#工作区操作" class="headerlink" title="工作区操作"></a>工作区操作</h3><blockquote>
<p>查询状态</p>
</blockquote>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git status</span><br></pre></td></tr></table></figure>

<h3 id="远程操作"><a href="#远程操作" class="headerlink" title="远程操作"></a>远程操作</h3><h4 id="分支管理"><a href="#分支管理" class="headerlink" title="分支管理"></a>分支管理</h4><blockquote>
<p>列出分支</p>
</blockquote>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">abel@xiaozanbiao:~/xxxx$ git branch -a</span><br><span class="line">* master</span><br><span class="line">  remotes/origin/HEAD -&gt; origin/master</span><br><span class="line">  remotes/origin/abel_learn</span><br><span class="line">  remotes/origin/develop_xcs</span><br><span class="line">  remotes/origin/master</span><br></pre></td></tr></table></figure>

<p>这个里面将会显示远程分支和本地分支；</p>
<blockquote>
<p>将远程的分支切换到本地分支</p>
</blockquote>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git checkout -b &lt;本地名称&gt; &lt;远程地址&gt;</span><br><span class="line">git checkout -b abel_learn origin/develop_xcs</span><br></pre></td></tr></table></figure>

<p>在操作的时候，需要将远程的分支，在本地做一次checkout</p>
<p>在本地切换分支，切换将直接使用checkout</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">[root@test-qingzhou-01 new_project_server]<span class="comment"># git checkout master</span></span><br><span class="line">Switched to branch <span class="string">&#x27;master&#x27;</span></span><br><span class="line">Your branch is behind <span class="string">&#x27;origin/master&#x27;</span> by 225 commits, and can be fast-forwarded.</span><br><span class="line">  (use <span class="string">&quot;git pull&quot;</span> to update your <span class="built_in">local</span> branch)</span><br><span class="line">[root@test-qingzhou-01 new_project_server]<span class="comment"># git branch</span></span><br><span class="line">  develop_xcs</span><br><span class="line">* master</span><br><span class="line">[root@test-qingzhou-01 new_project_server]<span class="comment"># git branch develop_xcs</span></span><br><span class="line">fatal: A branch named <span class="string">&#x27;develop_xcs&#x27;</span> already exists.</span><br></pre></td></tr></table></figure>

<blockquote>
<p>删除分支</p>
</blockquote>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git branch -d [branchname]</span><br></pre></td></tr></table></figure>

<blockquote>
<p>合并分支</p>
</blockquote>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git merge [otherbranch]</span><br></pre></td></tr></table></figure>

<blockquote>
<p>转移文件</p>
</blockquote>
<p>这个指令的好处是不会影响文件历史日志，如果直接删除并且增加那就比较麻烦了。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git mv <span class="built_in">source</span> dst</span><br></pre></td></tr></table></figure>

<h4 id="分支合并"><a href="#分支合并" class="headerlink" title="分支合并"></a>分支合并</h4><p>之前工作中使用svn来做分支管理。如果在trunk里面修改的bug需要合并到release分支的时候，需要使用merge来操作。</p>
<p>在git里面也有如此的概念，使用的是遴选（cherry pick）。在vscode里面使用git插件就能做这个操作了。有空可以研究一下具体如何通过命令行来出来这个事情。</p>
<p>使用命令行来使用；</p>
<figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">PS</span> D:\work\trunk\xxxx&gt; git cherry<span class="literal">-pick</span> <span class="number">7</span>e1e57d</span><br><span class="line">[<span class="type">VerDemo</span> <span class="type">e610a68</span>] 【需求】 <span class="comment">#1367 服务器增加日志，检查登录无法加载角色的问题 防止出现“保留房间超时被释放”</span></span><br><span class="line"> Date: Tue Mar <span class="number">23</span> <span class="number">20</span>:<span class="number">01</span>:<span class="number">32</span> <span class="number">2021</span> +<span class="number">0800</span></span><br><span class="line"> <span class="number">1</span> file changed, <span class="number">1</span> insertion(+), <span class="number">1</span> deletion(-)</span><br><span class="line"><span class="built_in">PS</span> D:\work\trunk\xxxx&gt; git push</span><br><span class="line">Enumerating objects: <span class="number">11</span>, done.</span><br><span class="line">Counting objects: <span class="number">100</span>% (<span class="number">11</span>/<span class="number">11</span>), done.</span><br><span class="line">Delta compression <span class="keyword">using</span> up to 8 threads</span><br><span class="line">Compressing objects: <span class="number">100</span>% (<span class="number">6</span>/<span class="number">6</span>), done.</span><br><span class="line">Writing objects: <span class="number">100</span>% (<span class="number">6</span>/<span class="number">6</span>), <span class="number">619</span> bytes | <span class="number">619.00</span> KiB/s, done.</span><br><span class="line">Total <span class="number">6</span> (delta <span class="number">5</span>), reused <span class="number">0</span> (delta <span class="number">0</span>), pack<span class="literal">-reused</span> <span class="number">0</span></span><br><span class="line">remote: Powered by GITEE.COM [<span class="type">GNK</span>-<span class="number">5.0</span>]</span><br><span class="line">To https://gitee.com/xxxx/xxx.git</span><br><span class="line">   f9819ca..e610a68  VerDemo -&gt; VerDemo</span><br></pre></td></tr></table></figure>

<p><a target="_blank" rel="noopener" href="http://www.ruanyifeng.com/blog/2020/04/git-cherry-pick.html">git cherry-pick 教程</a></p>
<p>git rebase 和 git cherry pick 有些类似。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">fatal: You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).</span><br><span class="line">Please, commit your changes before you merge.</span><br><span class="line"><span class="comment"># 使用命令放弃 git cherry-pick 变更</span></span><br><span class="line">git cherry-pick --abort </span><br></pre></td></tr></table></figure>

<figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">would clobber existing tag</span><br></pre></td></tr></table></figure>

<p>本地的tag和远程的tag冲突。</p>
<p>I’m using git in VSCodium and each time I try to pull git is complaining.</p>
<p>Looking into the log I see</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&gt; git pull --tags origin master</span><br><span class="line">From https://github.com/MY/REPO</span><br><span class="line"> * branch            master     -&gt; FETCH_HEAD</span><br><span class="line"> ! [rejected]        latest     -&gt; latest  (would clobber existing tag)</span><br><span class="line">   9428765..935da94  master     -&gt; origin/master</span><br><span class="line"></span><br><span class="line">git fetch --tags -f</span><br></pre></td></tr></table></figure>

<h2 id="git-修改远程的目录"><a href="#git-修改远程的目录" class="headerlink" title="git 修改远程的目录"></a>git 修改远程的目录</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看全部远程地址</span></span><br><span class="line">git remote -v</span><br><span class="line"><span class="comment"># 保存远程地址</span></span><br><span class="line">git remote set-url --add origin http://safjdklasjkflda</span><br><span class="line">git push -u other_origin master</span><br><span class="line">git pull -u other_origin master</span><br></pre></td></tr></table></figure>

<h2 id="git转换换行符（回车）"><a href="#git转换换行符（回车）" class="headerlink" title="git转换换行符（回车）"></a>git转换换行符（回车）</h2><p>git配置一共分为3个级别，可以通过这个命令来查看。</p>
<figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git config --system --list</span><br><span class="line">git config --global --list</span><br><span class="line">git config --local --list</span><br></pre></td></tr></table></figure>

<p>这个概念类似于环境变量。</p>
<p>其中 core.autocrlf 是决定了文件的回车方式。</p>
<p>true：提交的时候自动将CRLF转换成LF，签出时自动将LF转换成CRLF；<br>input：提交的时候CRLF转换成LF，签出时不转换；<br>false：将回车记录到库中</p>
<figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git config --global core.autocrlf [true|input|false]</span><br></pre></td></tr></table></figure>

<p>pull 根据不同的配置，可等于 fetch + merge 或 fetch + rebase。具体了解可继续读下去。</p>
<h2 id="tags冲突"><a href="#tags冲突" class="headerlink" title="tags冲突"></a>tags冲突</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看远程tags</span></span><br><span class="line">git ls-remote -t</span><br><span class="line"><span class="comment"># 查看本地tags</span></span><br><span class="line">git tag -l</span><br><span class="line"><span class="comment"># 删除本地与远程不一致的tag</span></span><br><span class="line">git tag -d tag名字</span><br><span class="line"><span class="comment"># 重新拉取远程tag</span></span><br><span class="line">git fetch origin --prune-tags</span><br></pre></td></tr></table></figure>

<p>实例：</p>
<figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">PS</span> D:\work\trunk\new_project_server&gt; git <span class="built_in">ls</span><span class="literal">-remote</span> <span class="literal">-t</span>  </span><br><span class="line">From http://xxxxxxxxxxxxxxx.git</span><br><span class="line"><span class="number">0285</span>d7e51bb70b59f132831d8593bb09f1b2ae90        refs/tags/CETag</span><br><span class="line"><span class="number">22</span>bb6f654eab74d570007e2644b6874fc0e2d4fd        refs/tags/demoTag</span><br><span class="line"><span class="number">5428836</span>d1c8f9996987179630cba7f86e00f07df        refs/tags/demoTag^&#123;&#125;</span><br><span class="line"><span class="number">48880</span>c2a1b10d71c47c4b1e1fa95ebdf88217924        refs/tags/v0.<span class="number">0.1</span></span><br><span class="line"><span class="number">5428836</span>d1c8f9996987179630cba7f86e00f07df        refs/tags/v0.<span class="number">0.1</span>^&#123;&#125;</span><br><span class="line"><span class="number">7</span>de8e2d0af4841ec688ba2a1a35dcc84a91bbb9e        refs/tags/verCE</span><br><span class="line"><span class="built_in">PS</span> D:\work\trunk\new_project_server&gt; git tag <span class="literal">-l</span> </span><br><span class="line">CETag</span><br><span class="line">demoTag</span><br><span class="line">v0.<span class="number">0.1</span></span><br><span class="line">verCE</span><br><span class="line"><span class="built_in">PS</span> D:\work\trunk\new_project_server&gt; git tag <span class="literal">-d</span> CETag</span><br><span class="line">Deleted tag <span class="string">&#x27;CETag&#x27;</span> (was <span class="number">805</span>af40b)</span><br><span class="line"><span class="built_in">PS</span> D:\work\trunk\new_project_server&gt; git pull -<span class="literal">-tags</span> origin develop</span><br><span class="line">From http://xxxxxxxxxxxxxxx</span><br><span class="line"> * branch              develop    -&gt; FETCH_HEAD</span><br><span class="line"> * [<span class="type">new</span> <span class="type">tag</span>]           CETag      -&gt; CETag</span><br><span class="line">Already up to date.</span><br></pre></td></tr></table></figure>

<p>服务器报错</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">PS D:\work\trun&gt; git fetch --tags -f</span><br><span class="line">warning: ----------------- SECURITY WARNING ----------------</span><br><span class="line">warning: | TLS certificate verification has been disabled! |</span><br><span class="line">warning: ---------------------------------------------------</span><br><span class="line">warning: HTTPS connections may not be secure. See https://aka.ms/gcmcore-tlsverify <span class="keyword">for</span> more information.</span><br><span class="line">warning: ----------------- SECURITY WARNING ----------------</span><br><span class="line">warning: | TLS certificate verification has been disabled! |</span><br><span class="line">warning: ---------------------------------------------------</span><br><span class="line">warning: HTTPS connections may not be secure. See https://aka.ms/gcmcore-tlsverify <span class="keyword">for</span> more information.</span><br></pre></td></tr></table></figure>

<p>git撤销掉本地的commit</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git reset HEAD~</span><br></pre></td></tr></table></figure>

<p>有时候git的提交我们需要回滚已经在本地提交的东西。可以通过执行。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Reset current branch to this commit</span><br><span class="line">git push -f origin/develop</span><br></pre></td></tr></table></figure>

<p>reset 模式</p>
<p>git reset –-soft：回退到某个版本，只回退了commit的信息，不会恢复到index file一级。如果还要提交，直接commit即可<br>git reset -–hard：彻底回退到某个版本，本地的源码也会变为上一个版本的内容，撤销的commit中所包含的更改被冲掉</p>
<p>删除分支</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">$ git branch -d develop_pos</span><br><span class="line">Deleted branch develop_pos (was 83fa957c).</span><br><span class="line">$ git push origin --delete develop_pos</span><br><span class="line">remote: . Processing 1 references</span><br><span class="line">remote: Processed 1 references <span class="keyword">in</span> total</span><br><span class="line">http://xxxxx.git</span><br><span class="line"> - [deleted]           develop_pos</span><br></pre></td></tr></table></figure>

<h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul>
<li>[1] <a target="_blank" rel="noopener" href="https://www.runoob.com/git/git-tutorial.html">Git菜鸟教程</a></li>
<li>[2] <a target="_blank" rel="noopener" href="https://www.liaoxuefeng.com/wiki/896043488029600">廖雪峰-Git教程</a></li>
<li>[3] <a target="_blank" rel="noopener" href="https://git-scm.com/book/zh/v2">官网手册</a></li>
<li>[4] <a target="_blank" rel="noopener" href="https://stackoverflow.com/questions/58031165/how-to-get-rid-of-would-clobber-existing-tag">clobber-existing-tag</a></li>
<li>[5] <a target="_blank" rel="noopener" href="https://www.zhihu.com/question/38305012">git pull 和 git fetch的区别？</a></li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://example.com/2020/11/04/2020/2020-11-04-learn_git/" data-id="ckrn3an6z000h20xw7v0500z0" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/git/" rel="tag">git</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-2020/2020-11-04-redis-乐观锁" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/11/04/2020/2020-11-04-redis-%E4%B9%90%E8%A7%82%E9%94%81/" class="article-date">
  <time datetime="2020-11-03T16:00:00.000Z" itemprop="datePublished">2020-11-04</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/11/04/2020/2020-11-04-redis-%E4%B9%90%E8%A7%82%E9%94%81/">redis-乐观锁</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>在使用多服务器操作redis的时候，需要考虑到数据同步的问题；本文来记录一下redis里面事务的用法。</p>
<h1 id="思路"><a href="#思路" class="headerlink" title="思路"></a>思路</h1><p>乐观锁每次操作的时候，都认为自己能拿到锁资源。所以吞吐量比较好。</p>
<p>策略：提交版本必须大于记录当前版本才能执行更新。</p>
<p>悲观锁是认为每次都需要拿数据时候，都会发生争抢。</p>
<p>策略为每次都会阻塞方式拿到资源才开始做自己操作。</p>
<p>乐观锁不会有阻塞，吞吐量比较大，编写难度也会简单。</p>
<h1 id="Redis指令和实验"><a href="#Redis指令和实验" class="headerlink" title="Redis指令和实验"></a>Redis指令和实验</h1><table>
<thead>
<tr>
<th align="left">命令</th>
<th align="left">意义</th>
</tr>
</thead>
<tbody><tr>
<td align="left">WATCH key [key …]</td>
<td align="left">监视一个(或多个) key ，如果在事务执行之前这个(或这些) key 被其他命令所改动，那么事务将被打断。</td>
</tr>
<tr>
<td align="left">MULTI</td>
<td align="left">标记一个事务块的开始。事务块内的多条命令会按照先后顺序被放进一个队列当中，最后由 EXEC 命令原子性(atomic)地执行。</td>
</tr>
<tr>
<td align="left">EXEC</td>
<td align="left">执行所有事务块内的命令。</td>
</tr>
</tbody></table>
<p>通过指令来描述一次事务的操作：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 监视 key ，且事务成功执行</span></span><br><span class="line"></span><br><span class="line">redis&gt; WATCH lock lock_times</span><br><span class="line">OK</span><br><span class="line"></span><br><span class="line">redis&gt; MULTI</span><br><span class="line">OK</span><br><span class="line"></span><br><span class="line">redis&gt; SET lock <span class="string">&quot;huangz&quot;</span></span><br><span class="line">QUEUED</span><br><span class="line"></span><br><span class="line">redis&gt; INCR lock_times</span><br><span class="line">QUEUED</span><br><span class="line"></span><br><span class="line">redis&gt; EXEC</span><br><span class="line">1) OK</span><br><span class="line">2) (<span class="built_in">integer</span>) 1</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 监视 key ，且事务被打断</span></span><br><span class="line"></span><br><span class="line">redis&gt; WATCH lock lock_times</span><br><span class="line">OK</span><br><span class="line"></span><br><span class="line">redis&gt; MULTI</span><br><span class="line">OK</span><br><span class="line"></span><br><span class="line">redis&gt; SET lock <span class="string">&quot;joe&quot;</span>        <span class="comment"># 就在这时，另一个客户端修改了 lock_times 的值</span></span><br><span class="line">QUEUED</span><br><span class="line"></span><br><span class="line">redis&gt; INCR lock_times</span><br><span class="line">QUEUED</span><br><span class="line"></span><br><span class="line">redis&gt; EXEC                  <span class="comment"># 因为 lock_times 被修改， joe 的事务执行失败</span></span><br><span class="line">(nil)</span><br></pre></td></tr></table></figure>

<p>上述例子是实现了，lock_times和操作lock中的内容时候，事务冲突之后，被打断的情况。</p>
<h1 id="go语言测试"><a href="#go语言测试" class="headerlink" title="go语言测试"></a>go语言测试</h1><h1 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h1><ul>
<li>[1] <a target="_blank" rel="noopener" href="http://doc.redisfans.com/">Redis 命令参考</a></li>
<li>[2] <a target="_blank" rel="noopener" href="https://github.com/gomodule/redigo">Golang Redis库</a></li>
<li>[3] <a target="_blank" rel="noopener" href="https://www.jianshu.com/p/62f0b9ce7584">Go语言如何使用redis</a></li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://example.com/2020/11/04/2020/2020-11-04-redis-%E4%B9%90%E8%A7%82%E9%94%81/" data-id="ckrn3an70000j20xw0yw3azqf" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/redis/" rel="tag">redis</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-2020/2020-11-03-docker[0]-nginx" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/11/03/2020/2020-11-03-docker%5B0%5D-nginx/" class="article-date">
  <time datetime="2020-11-02T16:00:00.000Z" itemprop="datePublished">2020-11-03</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/11/03/2020/2020-11-03-docker%5B0%5D-nginx/">docker运行nginx</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>学习docker</p>
<ul>
<li><a href="#%E7%AE%80%E4%BB%8B">简介</a></li>
<li><a href="#%E5%AE%89%E8%A3%85">安装</a></li>
<li><a href="#%E5%9F%BA%E6%9C%AC%E6%93%8D%E4%BD%9C">基本操作</a></li>
<li><a href="#%E5%AE%89%E8%A3%85mysql">安装mysql</a></li>
<li><a href="#%E5%AE%89%E8%A3%85nginx">安装nginx</a></li>
<li><a href="#%E6%89%A9%E5%B1%95">扩展</a></li>
<li><a href="#%E4%BF%AE%E6%94%B9docker-ulimit">修改docker ulimit</a></li>
<li><a href="#%E5%AE%89%E8%A3%85mysql-1">安装mysql</a></li>
<li><a href="#%E5%BC%95%E7%94%A8">引用</a></li>
</ul>
<h1 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h1><p>docker是为了简化外网服务器软件环境部署的工作。现在初浅的理解是，可以在linux机器上通过docker单独安装mysql,nginx,应用程序的也可以跑在一个docker之上。</p>
<ul>
<li>Docker 包括三个基本概念:</li>
</ul>
<ul>
<li>镜像（Image）：Docker 镜像（Image），就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。</li>
<li>容器（Container）：镜像（Image）和容器（Container）的关系，就像是面向对象程序设计中的类和实例一样，镜像是静态的定义，容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。</li>
<li>仓库（Repository）：仓库可看着一个代码控制中心，用来保存镜像。</li>
</ul>
<h1 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h1><p>参考了<a target="_blank" rel="noopener" href="https://cloud.tencent.com/developer/labs/lab/10054">腾讯在线实验</a> <a target="_blank" rel="noopener" href="https://www.runoob.com/docker/centos-docker-install.html">菜鸟入门</a> 可以很快速的将docker部署到你的服务器上。</p>
<ul>
<li>可能需要卸载掉老的docker</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">$ sudo yum remove docker \</span><br><span class="line">                  docker-client \</span><br><span class="line">                  docker-client-latest \</span><br><span class="line">                  docker-common \</span><br><span class="line">                  docker-latest \</span><br><span class="line">                  docker-latest-logrotate \</span><br><span class="line">                  docker-logrotate \</span><br><span class="line">                  docker-engine</span><br></pre></td></tr></table></figure>

<ul>
<li>设置仓库</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">$ sudo yum install -y yum-utils \</span><br><span class="line">  device-mapper-persistent-data \</span><br><span class="line">  lvm2</span><br><span class="line">$ sudo yum-config-manager \</span><br><span class="line">    --add-repo \</span><br><span class="line">    https://download.docker.com/linux/centos/docker-ce.repo</span><br><span class="line">$ sudo yum install docker-ce docker-ce-cli containerd.io</span><br></pre></td></tr></table></figure>

<ul>
<li>安装</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo yum install docker-ce docker-ce-cli containerd.io</span><br></pre></td></tr></table></figure>

<p>安装完成之后，可以通过docker -v来查看当前docker的版本信息。</p>
<ul>
<li>使用国内加速</li>
</ul>
<p>创建或修改 /etc/docker/daemon.json 文件</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">&quot;registry-mirrors&quot;</span>: [</span><br><span class="line">    <span class="string">&quot;https://registry.docker-cn.com&quot;</span>,</span><br><span class="line">    <span class="string">&quot;http://hub-mirror.c.163.com&quot;</span>,</span><br><span class="line">    <span class="string">&quot;https://docker.mirrors.ustc.edu.cn&quot;</span></span><br><span class="line">  ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h1 id="基本操作"><a href="#基本操作" class="headerlink" title="基本操作"></a>基本操作</h1><ul>
<li>运行一个容器</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7</span><br></pre></td></tr></table></figure>

<ul>
<li>查询容器</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker ps -a</span><br></pre></td></tr></table></figure>

<ul>
<li>使用 docker start 启动一个已停止的容器：</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker start b750bbbcfd88</span><br></pre></td></tr></table></figure>

<ul>
<li>后台运行 （增加-d的指令）</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run -itd --name ubuntu-test ubuntu /bin/bash</span><br></pre></td></tr></table></figure>

<ul>
<li>停止一个容器</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker stop &lt;容器 ID&gt;</span><br></pre></td></tr></table></figure>
<ul>
<li>进入容器</li>
</ul>
<p>docker attach 如果从这个容器退出，会导致容器的停止。</p>
<p>docker exec：推荐大家使用 docker exec 命令，因为此退出容器终端，不会导致容器的停止。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">docker attach 1e560fca3906 </span><br><span class="line">docker <span class="built_in">exec</span> -it 243c32535da7 /bin/bash</span><br></pre></td></tr></table></figure>

<ul>
<li>导出和导入容器</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker <span class="built_in">export</span> 1e560fca3906 &gt; ubuntu.tar</span><br></pre></td></tr></table></figure>

<ul>
<li>导入容器快照</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cat docker/ubuntu.tar | docker import - test/ubuntu:v1</span><br></pre></td></tr></table></figure>

<ul>
<li>下面的命令可以清理掉所有处于终止状态的容器。</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker container prune</span><br></pre></td></tr></table></figure>

<p>更多指令可以后续补充</p>
<h1 id="安装mysql"><a href="#安装mysql" class="headerlink" title="安装mysql"></a>安装mysql</h1><blockquote>
<p><a target="_blank" rel="noopener" href="https://www.runoob.com/docker/docker-install-mysql.html">参考菜鸟入门mysql安装</a><br><a target="_blank" rel="noopener" href="https://www.cnblogs.com/sablier/p/11605606.html">使用Docker搭建MySQL服务</a></p>
</blockquote>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 拉取mysql5.7版本</span></span><br><span class="line">docker pull mysql:5.7   <span class="comment"># 拉取 mysql 5.7</span></span><br><span class="line"><span class="comment"># 检查版本</span></span><br><span class="line">docker images</span><br><span class="line"><span class="comment"># 启动mysql</span></span><br><span class="line">docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7</span><br></pre></td></tr></table></figure>

<ul>
<li>-–name：容器名，此处命名为mysql</li>
<li>-e：配置信息，此处配置mysql的root用户的登陆密码</li>
<li>-p：端口映射，此处映射 主机3306端口 到 容器的3306端口</li>
<li>-d：源镜像名，此处为 mysql:5.7</li>
</ul>
<h1 id="安装nginx"><a href="#安装nginx" class="headerlink" title="安装nginx"></a>安装nginx</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"># 拉取版本</span><br><span class="line">docker pull nginx:latest</span><br><span class="line"># 检查版本</span><br><span class="line">docker images</span><br><span class="line"># 启动docker中的nginx</span><br><span class="line">docker run --name nginx-test -p 8080:80 -d nginx</span><br></pre></td></tr></table></figure>

<ul>
<li>–name nginx-test：容器名称。</li>
<li>-p 8080:80： 端口进行映射，将本地 8080 端口映射到容器内部的 80 端口。</li>
<li>-d nginx： 设置容器在在后台一直运行。</li>
</ul>
<p>可能需要去修改nginx里面的配置项目，我需要将这个服务器端口映射出来。<br>[docker 安装nginx 并部署](<a target="_blank" rel="noopener" href="https://blog.csdn.net/ddhsea/article/details/92203713%E3%80%82">https://blog.csdn.net/ddhsea/article/details/92203713。</a><br>里面有3个步骤</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"># 在自己目录下创建这些文件夹</span><br><span class="line">mkdir -p ~/nginx/www ~/nginx/logs ~/nginx/conf</span><br><span class="line"># 将容器中的nginx文件拷贝出来，通过docker ps出来实例编号。</span><br><span class="line">sudo docker cp 3bd71361a112:/etc/nginx/nginx.conf ~/nginx/conf</span><br><span class="line"># 启动的时候，绑定映射关系</span><br><span class="line">docker run --name yzgmweb -d -p 35981:8088 \</span><br><span class="line">    -v /root/nginx/conf/nginx.conf:/etc/nginx/nginx.conf\</span><br><span class="line">    -v /root/nginx/www:/usr/share/nginx/html\</span><br><span class="line">    -v /root/nginx/logs:/var/log/nginx -d docker.io/nginx</span><br></pre></td></tr></table></figure>

<ul>
<li>-p 8080:80： 端口进行映射，将本地 8080 端口映射到容器内部的 80 端口。</li>
<li>-v ~/nginx/conf/nginx.conf:/etc/nginx/nginx.conf 将本地文件映射到容器内部。</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">➜  ~ docker run -d -p 6381:6379 --name redis-9 -d redis</span><br><span class="line">16c1db84bc5156c099bf476e83d1951398615e2819c94cfdf041ec8fd5c37284</span><br><span class="line">➜  ~ docker ps</span><br><span class="line">CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                       NAMES</span><br><span class="line">16c1db84bc51   redis     <span class="string">&quot;docker-entrypoint.s…&quot;</span>   5 seconds ago   Up 3 seconds   0.0.0.0:6381-&gt;6379/tcp, :::6381-&gt;6379/tcp   redis-9</span><br><span class="line">6af8e5268b90   redis     <span class="string">&quot;docker-entrypoint.s…&quot;</span>   6 days ago      Up 6 days      0.0.0.0:6380-&gt;6379/tcp, :::6380-&gt;6379/tcp   redis-10</span><br></pre></td></tr></table></figure>

<h1 id="扩展"><a href="#扩展" class="headerlink" title="扩展"></a>扩展</h1><p>后续如果有时间，可以再去研究一下 docker compose &amp; swarm；dockerfile之类的东西。再做记录。</p>
<h1 id="修改docker-ulimit"><a href="#修改docker-ulimit" class="headerlink" title="修改docker ulimit"></a>修改docker ulimit</h1><p>[How to increase number of open files limit]](<a target="_blank" rel="noopener" href="https://mtyurt.net/post/docker-how-to-increase-number-of-open-files-limit.html">https://mtyurt.net/post/docker-how-to-increase-number-of-open-files-limit.html</a>)</p>
<p>docker run –ulimit nofile=90000:90000 <image-tag></p>
<h1 id="安装mysql-1"><a href="#安装mysql-1" class="headerlink" title="安装mysql"></a>安装mysql</h1><p>设置docker的子目录</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run -d -p 3307:3306 --name my_mariadb -v /data/mariadb/data/:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root mariadb:lastest</span><br></pre></td></tr></table></figure>

<p>将本地端口 3307 映射到 docker 端口 3306</p>
<h1 id="引用"><a href="#引用" class="headerlink" title="引用"></a>引用</h1><ul>
<li><a target="_blank" rel="noopener" href="https://www.docker.com/">官方网站</a></li>
<li><a target="_blank" rel="noopener" href="https://www.runoob.com/docker/docker-tutorial.html">菜鸟入门</a></li>
<li><a target="_blank" rel="noopener" href="https://cloud.tencent.com/developer/labs/lab/10054">腾讯在线实验</a></li>
<li><a target="_blank" rel="noopener" href="https://www.jianshu.com/p/721d971c3cd7">Docker中安装nginx与自定义配置</a></li>
<li><a target="_blank" rel="noopener" href="https://www.cnblogs.com/youclk/p/8453526.html">docker compose swarm</a></li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://example.com/2020/11/03/2020/2020-11-03-docker[0]-nginx/" data-id="ckrn3an6w000920xwhdaqenki" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/%E8%BF%90%E7%BB%B4/" rel="tag">运维</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-2020/2020-11-03-go[1]-程序结构" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/11/03/2020/2020-11-03-go%5B1%5D-%E7%A8%8B%E5%BA%8F%E7%BB%93%E6%9E%84/" class="article-date">
  <time datetime="2020-11-02T16:00:00.000Z" itemprop="datePublished">2020-11-03</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/11/03/2020/2020-11-03-go%5B1%5D-%E7%A8%8B%E5%BA%8F%E7%BB%93%E6%9E%84/">go[1]-程序结构</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>记录golang的程序结构相关知识。</p>
<ul>
<li><a href="#1%E5%87%BD%E6%95%B0%E5%AE%9A%E4%B9%89">1.函数定义</a></li>
<li><a href="#2%E5%8C%BF%E5%90%8D%E5%87%BD%E6%95%B0">2.匿名函数</a></li>
<li><a href="#3%E5%BB%B6%E8%BF%9F%E8%B0%83%E7%94%A8">3.延迟调用</a></li>
<li><a href="#4%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86">4.错误处理</a></li>
<li><a href="#5panic-recover">5.panic recover</a></li>
<li><a href="#6%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86%E7%AD%96%E7%95%A5">6.错误处理策略</a></li>
<li><a href="#7%E6%B5%81%E7%A8%8B%E6%8E%A7%E5%88%B6">7.流程控制</a><ul>
<li><a href="#1for-statements">1.for statements</a></li>
<li><a href="#2-switch-statements">2. switch statements</a></li>
</ul>
</li>
<li><a href="#8%E5%AF%BC%E5%85%A5%E5%8C%85">8.导入包</a></li>
<li><a href="#9%E7%BB%84%E7%BB%87%E7%BB%93%E6%9E%84">9.组织结构</a></li>
<li><a href="#10%E6%9D%83%E9%99%90">10.权限</a></li>
<li><a href="#11%E5%88%9D%E5%A7%8B%E5%8C%96">11.初始化</a></li>
<li><a href="#12%E5%86%85%E9%83%A8%E5%8C%85">12.内部包</a></li>
<li><a href="#13%E4%BE%9D%E8%B5%96%E7%AE%A1%E7%90%86">13.依赖管理</a></li>
<li><a href="#14%E7%A8%8B%E5%BA%8F%E7%9A%84%E7%9B%AE%E5%BD%95%E5%BB%BA%E8%AE%AE">14.程序的目录建议</a></li>
<li><a href="#defer%E8%AF%A6%E8%A7%A3">defer详解</a></li>
</ul>
<p>函数是对一系列语句打包的单元。</p>
<h1 id="1-函数定义"><a href="#1-函数定义" class="headerlink" title="1.函数定义"></a>1.函数定义</h1><p>func name(parameter-list)(result-list) {<br>    body<br>}<br>能支持多返回值，或者无返回值。匿名函数是指的没有名字的函数。函数可以成为一个结构体字段，也能成为通道来传递。<br>匿名函数是一种常见的重构手段。可以将大函数分解成多个相对独立的匿名函数块，这样主干部分的调用函数将会更加简洁，做到框架和细节分离。</p>
<h1 id="2-匿名函数"><a href="#2-匿名函数" class="headerlink" title="2.匿名函数"></a>2.匿名函数</h1><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">test</span><span class="params">(x <span class="keyword">int</span>)</span><span class="title">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">        fmt.Println(x)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">    f := test(<span class="number">123</span>)</span><br><span class="line">    f()</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>通过匿名函数将变量123缓存再函数中。最后调用的时候，可以很方便的将123输出。</p>
<blockquote>
<p>警告：捕获迭代变量Go词法作用于陷阱。即使经验丰富程序员也会在这个问题上犯错误。</p>
</blockquote>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> rmdirs []<span class="function"><span class="keyword">func</span><span class="params">()</span></span></span><br><span class="line"><span class="keyword">for</span> _,d := <span class="keyword">range</span> tempDirs() &#123;</span><br><span class="line">    dir := d</span><br><span class="line">    os.MkdirAll(dir,<span class="number">0755</span>)</span><br><span class="line">    rmdirs = <span class="built_in">append</span>(rmdirs,<span class="function"><span class="keyword">func</span><span class="params">()</span></span>&#123;</span><br><span class="line">        os.RemoveAll(dir)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span> _,rmdir := <span class="keyword">range</span>(rmdirs&#123;</span><br><span class="line">     rmdir()</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>为啥要将d重新赋值成dir？原因就在循环变量中的作用域。如果直接使用d将会删除的相同的目录。这样的问题在使用defer语句也有相同问题。</p>
<h1 id="3-延迟调用"><a href="#3-延迟调用" class="headerlink" title="3.延迟调用"></a>3.延迟调用</h1><p>defer语句是指注册一个函数，再稍后调用。一般用于资源释放，解锁，错误处理等操作。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span> <span class="params">()</span></span> &#123;</span><br><span class="line">f,err :=os.Open(<span class="string">&quot;./main.go&quot;</span>)</span><br><span class="line"><span class="keyword">if</span> err !=<span class="literal">nil</span> &#123;</span><br><span class="line">    fmt.Println(<span class="string">&quot;err&quot;</span>)</span><br><span class="line">    <span class="keyword">return</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">defer</span> f.<span class="built_in">close</span>() <span class="comment">// 提前注册释放</span></span><br><span class="line"><span class="comment">// 文件读写</span></span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>延时调用遵循FILO，堆栈式的调用。简单理解就是先进后出。<br>错误的用法<br>func main() {<br>   for I := 0; I&lt;1000000; I++ {<br>        path := fmt.Sprintf(“./log/%d.txt”,i)<br>        f, err := os.Open(path)<br>        if err != nil {<br>            fmt.Println(err)<br>            continue<br>        }<br>        defer f.close() // 其实要等到这个循环全部做完，才会调用的<br>        // 操作文件<br>   }<br>}<br>这种情况，应该将操作文件的部分封装成小函数，避免再循环过程中，直接使用defer。<br>性能方面，defer方式需要花掉比较大的代价。</p>
<h1 id="4-错误处理"><a href="#4-错误处理" class="headerlink" title="4.错误处理"></a>4.错误处理</h1><p>调侃go的人，说错误处理有些返祖。”stuck in 70’s”。<br>提供了error的接口。<br>err := errors.New(“division by zero”)<br>这样就能构造一个出来。有经验的程序员一般都会对错误做一些预计的处理。函数如果返回类型为error时候，都需要判断一下错误信息是否为空。</p>
<h1 id="5-panic-recover"><a href="#5-panic-recover" class="headerlink" title="5.panic recover"></a>5.panic recover</h1><p>类似于exception/try/catch结构化异常。函数原型如下。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">panic</span><span class="params">(v <span class="keyword">interface</span>&#123;&#125;)</span></span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">recover</span><span class="params">()</span> <span class="title">interface</span></span>&#123;&#125;</span><br></pre></td></tr></table></figure>
<p>他们是内置函数，不是语句。panic将会终端当前流程（如：数组访问越界、空指针引用），并且触发defer的调用。在延时调用中可以通过recover捕获其中的报错。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">    <span class="keyword">defer</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">       <span class="keyword">if</span> err := <span class="built_in">recover</span>(); err!=<span class="literal">nil</span> &#123;</span><br><span class="line">          fmt.Println(err)</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>recover必须在panic触发之后才能捕获到错误，而且只能在延时调用函数中才能工作。不能在函数内部直接使用。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">catch</span><span class="params">()</span></span> &#123;</span><br><span class="line">      log.Println(<span class="string">&quot;catch:&quot;</span>,<span class="built_in">recover</span>())</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">      <span class="keyword">defer</span> catch() <span class="comment">// 捕获</span></span><br><span class="line">      <span class="keyword">defer</span> log.Println(<span class="built_in">recover</span>())<span class="comment">// 失败</span></span><br><span class="line">      <span class="keyword">defer</span> <span class="built_in">recover</span>() <span class="comment">// 失败</span></span><br><span class="line">      <span class="built_in">panic</span>(<span class="string">&quot;i am dead&quot;</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>调试期间可以使用 runtime/debug.PrintStack。获取完整的堆栈信息。将会输出到标准错误日志中。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">// PrintStack prints to standard error the stack trace returned by runtime.Stack.</span><br><span class="line">func PrintStack() &#123;</span><br><span class="line">	os.Stderr.Write(Stack())</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>使用panic的时候，建议是遇到了不可恢复、导致系统无法运行的错误，否则不要使用。服务器端口占用、文件无法打开、数据库未启动。这种错误超出了程序员的控制的。程序必须停止的情况。</p>
<h1 id="6-错误处理策略"><a href="#6-错误处理策略" class="headerlink" title="6.错误处理策略"></a>6.错误处理策略</h1><p>1.将错误信息上报给调用者，并且添加额外的上下文信息；错误信息最好能描述出问题的需要的参数；<br>2.如果错误是偶发的，或者是不可预计问题导致。我们需要构造有限次数的重试机制，避免无限制的重试；<br>3.出现错误之后，程序其实已经无法执行，那就需要将错误信息输出出来，并且将程序终止；避免出现更多的问题。比如数据库已经无法写入了，机器的硬盘已经无法写入文件内容了；<br>4.错误不致命，只需要在错误级别日志中输出，然后继续执行程序；<br>5.可以忽略掉一些无关紧要的错误。<br>在Go中，函数被当作第一类型（first-class values），函数像其他值一样，拥有类型，可以传送，赋值给其他变量。函数值不能做比较，所以不能当成map的key。</p>
<h1 id="7-流程控制"><a href="#7-流程控制" class="headerlink" title="7.流程控制"></a>7.流程控制</h1><h2 id="1-for-statements"><a href="#1-for-statements" class="headerlink" title="1.for statements"></a>1.for statements</h2><p>查看文档：</p>
<figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// file:c:/go/doc/go_spec.html#For_statements</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 根据条件循环</span></span><br><span class="line"><span class="keyword">for</span> a &lt; b &#123;</span><br><span class="line">	a *= <span class="number">2</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 用于做列表循环</span></span><br><span class="line">RangeClause = [ ExpressionList <span class="string">&quot;=&quot;</span> | IdentifierList <span class="string">&quot;:=&quot;</span> ] <span class="string">&quot;range&quot;</span> Expression .</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>标准目录为src、bin、pkg三个目录。<br>GOPATH可以指定几个目录，排在列表最前面的比当前工作空间优先级更高。go get默认会下载到第一个工作空间里面。备注：unix-like使用冒号分隔，windows使用;分割。<br>GOROOT指定工具链和标准库的存放位置。</p>
<h2 id="2-switch-statements"><a href="#2-switch-statements" class="headerlink" title="2. switch statements"></a>2. switch statements</h2><p><a target="_blank" rel="noopener" href="https://studygolang.com/articles/31379?fr=sidebar">fallthrough</a></p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line">    <span class="string">&quot;fmt&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">    a := <span class="number">2</span></span><br><span class="line">    <span class="keyword">switch</span> a &#123;</span><br><span class="line">    <span class="keyword">case</span> <span class="number">1</span>:</span><br><span class="line">        fmt.Println(<span class="string">&quot;a=1&quot;</span>)</span><br><span class="line">    <span class="keyword">case</span> <span class="number">2</span>:</span><br><span class="line">        fmt.Println(<span class="string">&quot;a=2&quot;</span>)</span><br><span class="line">        <span class="keyword">fallthrough</span></span><br><span class="line">    <span class="keyword">case</span> <span class="number">3</span>:</span><br><span class="line">        fmt.Println(<span class="string">&quot;a=3&quot;</span>)</span><br><span class="line">        <span class="keyword">case</span> <span class="number">4</span>:</span><br><span class="line">        fmt.Println(<span class="string">&quot;a=4&quot;</span>)</span><br><span class="line">    <span class="keyword">default</span>:</span><br><span class="line">        fmt.Println(<span class="string">&quot;default&quot;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h1 id="8-导入包"><a href="#8-导入包" class="headerlink" title="8.导入包"></a>8.导入包</h1><p>如果是系统级的包的导入</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">import &quot;net/http&quot;</span><br><span class="line">import osx &quot;github.com/apple/osx/lib&quot;</span><br><span class="line">import _ &quot;github.com/qyuhen/test&quot;</span><br><span class="line">import &quot;../lib&quot; // 相对路径引入</span><br></pre></td></tr></table></figure>
<h1 id="9-组织结构"><a href="#9-组织结构" class="headerlink" title="9.组织结构"></a>9.组织结构</h1><p>包由一个或多个保存在同一目录下的源文件组成。<br>包名和目录名称并无关系，不要求保持一致，举个例子，leaf里面的go的库。目录名为go，但是里面的包使用的名称为g。不影响使用，在import的时候是写go,语句里面写g。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&quot;github.com/name5566/leaf/go&quot;</span><br><span class="line">d := g.New(10)</span><br></pre></td></tr></table></figure>
<p>同一目录下的包名需要完全一致。下列有几个特殊的包名：</p>
<blockquote>
<p>main ：可执行入口<br>all: 标准库以及 GOPATH中能找到的所有包。<br>std,cmd：标准库工具链<br>documentations：存储文档信息、无法导入。</p>
</blockquote>
<h1 id="10-权限"><a href="#10-权限" class="headerlink" title="10.权限"></a>10.权限</h1><p>包内成员可以互相访问。只有大写字母的能被包外访问。当然也能通过unsafe.Pointer方式来反出数据并且调用。</p>
<h1 id="11-初始化"><a href="#11-初始化" class="headerlink" title="11.初始化"></a>11.初始化</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">func init() &#123;</span><br><span class="line">&#125; </span><br></pre></td></tr></table></figure>
<h1 id="12-内部包"><a href="#12-内部包" class="headerlink" title="12.内部包"></a>12.内部包</h1><p>将内部模块分离出来，单独包的形式维护。只能被父目录下的包访问，命名为internal目录下的包。</p>
<h1 id="13-依赖管理"><a href="#13-依赖管理" class="headerlink" title="13.依赖管理"></a>13.依赖管理</h1><p> 主要是解决三方依赖库文件冲突问题。这个概念是和内部包刚好相反，vendor目录是提供给当前工作目录，通用的目录。<br>注意：vendor比标准库有嫌隙更高。</p>
<h1 id="14-程序的目录建议"><a href="#14-程序的目录建议" class="headerlink" title="14.程序的目录建议"></a>14.程序的目录建议</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">  |</span><br><span class="line">  | mgr.go</span><br><span class="line">  |</span><br><span class="line">  -----ixxx</span><br><span class="line">       |</span><br><span class="line">       |</span><br><span class="line">       -----imgr.go</span><br><span class="line">  |</span><br><span class="line">  |</span><br><span class="line">  -----models</span><br><span class="line">       |</span><br><span class="line">       |</span><br><span class="line">       ------mgr_impl.go</span><br></pre></td></tr></table></figure>

<p>mgr.go 用于放置提供给外部调用函数；外部需要使用的类；</p>
<p>ixxx 目录放置模块的接口定义；</p>
<p>models 目录放置实现函数；</p>
<p>图中说明了绘制了依赖关系。这样能防止再外面循环引用的问题：</p>
<h1 id="defer详解"><a href="#defer详解" class="headerlink" title="defer详解"></a>defer详解</h1><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"></span><br></pre></td></tr></table></figure>

<p><a target="_blank" rel="noopener" href="https://imgchr.com/i/DM5bm4"><img src="https://s3.ax1x.com/2020/11/20/DM5bm4.png" alt="DM5bm4.png"></a></p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://example.com/2020/11/03/2020/2020-11-03-go[1]-%E7%A8%8B%E5%BA%8F%E7%BB%93%E6%9E%84/" data-id="ckrn3an6w000b20xwa1wke5pc" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/golang/" rel="tag">golang</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-2020/2020-11-03-go[0]-getstart" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/11/03/2020/2020-11-03-go%5B0%5D-getstart/" class="article-date">
  <time datetime="2020-11-02T16:00:00.000Z" itemprop="datePublished">2020-11-03</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/11/03/2020/2020-11-03-go%5B0%5D-getstart/">go[0]-入门</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>学习golang的入门的信息；本章只记录一下golang语言的历史。大量资料都来自于网上收集。</p>
<h2 id="历史"><a href="#历史" class="headerlink" title="历史"></a>历史</h2><p>Go语言（或 Golang）起源于 2007 年，并在 2009 年正式对外发布。Go 是非常年轻的一门语言，它的主要目标是“兼具 Python 等动态语言的开发速度和 C/C++ 等编译型语言的性能与安全性”。</p>
<h2 id="环境部署"><a href="#环境部署" class="headerlink" title="环境部署"></a>环境部署</h2><p><a target="_blank" rel="noopener" href="https://golang.org/">官方网站</a></p>
<h3 id="Linux"><a href="#Linux" class="headerlink" title="Linux"></a>Linux</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">tar -C /usr/<span class="built_in">local</span> -xzf go1.15.3.linux-amd64.tar.gz</span><br><span class="line"><span class="comment"># 设置环境变量</span></span><br><span class="line">/etc/profile</span><br><span class="line"><span class="variable">$HOME</span>/.profile</span><br><span class="line"><span class="built_in">export</span> PATH=<span class="variable">$PATH</span>:/usr/<span class="built_in">local</span>/go/bin</span><br></pre></td></tr></table></figure>

<h3 id="Windows"><a href="#Windows" class="headerlink" title="Windows"></a>Windows</h3><p>直接通过安装包安装；</p>
<h3 id="需要配置的环境变量"><a href="#需要配置的环境变量" class="headerlink" title="需要配置的环境变量"></a>需要配置的环境变量</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">GOPATH=D:\work\gopath</span><br><span class="line">export GOPROXY=https://goproxy.io,https://goproxy.cn,direct</span><br><span class="line"># 配置 GOPROXY 环境变量</span><br><span class="line">export GOPROXY=https://goproxy.io,direct</span><br><span class="line"># 还可以设置不走 proxy 的私有仓库或组，多个用逗号相隔（可选）</span><br><span class="line">export GOPRIVATE=git.mycompany.com,github.com/my/private</span><br><span class="line">$ export GO111MODULE=on</span><br><span class="line">$ export GOPROXY=https://goproxy.cn</span><br></pre></td></tr></table></figure>

<h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul>
<li>[1] <a target="_blank" rel="noopener" href="https://www.runoob.com/go/go-tutorial.html">Go语言菜鸟</a></li>
<li>[2] <a target="_blank" rel="noopener" href="http://c.biancheng.net/golang/">Go语言入门</a><h6 id="linux环境搭建"><a href="#linux环境搭建" class="headerlink" title="linux环境搭建"></a>linux环境搭建</h6>先解压缩golang的包<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tar -xf ./go.1.xxx.tar.gz -C /usr/local</span><br></pre></td></tr></table></figure>
使用go env查询具体的环境信息。通过编辑~/.bashrc文件的环境变量来修改配置。</li>
</ul>
<h6 id="go-build"><a href="#go-build" class="headerlink" title="go build"></a>go build</h6><table>
<thead>
<tr>
<th>参数</th>
<th>说明</th>
<th>示例</th>
</tr>
</thead>
<tbody><tr>
<td>-o</td>
<td>可执行文件名</td>
<td></td>
</tr>
<tr>
<td>-a</td>
<td>强制重编译所有包()包含标准库</td>
<td></td>
</tr>
<tr>
<td>-p</td>
<td>并行编译使用CPU核心数</td>
<td></td>
</tr>
<tr>
<td>-v</td>
<td>显示等待编译包名</td>
<td></td>
</tr>
<tr>
<td>-n</td>
<td>显示编译命令，但不执行</td>
<td></td>
</tr>
<tr>
<td>-x</td>
<td>显示正在执行的编译命令</td>
<td></td>
</tr>
<tr>
<td>-work</td>
<td>显示临时工作目录，完成后不删除</td>
<td></td>
</tr>
<tr>
<td>-race</td>
<td>启动数据竞争检查（旨在amd64</td>
<td></td>
</tr>
<tr>
<td>-gcflags</td>
<td>编译器参数</td>
<td></td>
</tr>
<tr>
<td>-ldflags</td>
<td>链接器参数</td>
<td></td>
</tr>
<tr>
<td>-race</td>
<td>开启DATA RACE检测</td>
<td></td>
</tr>
</tbody></table>
<p>编译器选项<br>| 参数 | 说明         |<br>| —- | ———— |<br>| -B   | 禁用越界检查 |<br>| -N   | 禁用优化     |<br>| -l   | 禁用内联     |<br>| -u   | 禁用unsafe   |<br>| -S   | 输出汇编代码 |<br>| -m   | 输出优化信息 |</p>
<p>ldflags:<br>| 参数 | 说明                                 |<br>| —- | ———————————— |<br>| -s   | 禁用符号表                           |<br>| -w   | 禁用DRAWF调试信息                    |<br>| -X   | 设置字符串全局变量值   -X ver=”0.99” |<br>| -H   | 设置可执行文件格式 -H windowsgui     |</p>
<p>详细参数可以通过<br>go tool compile -h<br>go tool link -h<br>获取更多信息也可以直接到<br>src/cmd/[compile|link]<br>目录下阅读doc.go文档。</p>
<h6 id="go-install"><a href="#go-install" class="headerlink" title="go install"></a>go install</h6><p>参数和go build一致，只是将编译结果安装到bin/pkg目录中。go install支持增量编译。如果没有修改，将会直接链接pkg目录中的静态包。编译器用buildid检查文件清单和导入依赖。<br>算法源码可以阅读<br>src/cmd/go/pkg.go</p>
<h6 id="go-get"><a href="#go-get" class="headerlink" title="go get"></a>go get</h6><p>下载第三方包到GOPATH列表中第一个工作目录。<br>| 参数      | 说明                               |<br>| ——— | ———————————- |<br>| -d        | 仅下载，不安装                     |<br>| -u        | 更新包，包括其依赖项               |<br>| -f        | 和-u配合，强制更新，不检测过期与否 |<br>| -t        | 下载测试代码所需的依赖包           |<br>| -insecure | 使用HTTP非安全协议                 |<br>| -v        | 输出详细信息verbose                |<br>| -x        | 显示正在执行的命令                 |</p>
<h6 id="go-env"><a href="#go-env" class="headerlink" title="go env"></a>go env</h6><p>显示全部环境变量</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">set GO111MODULE=</span><br><span class="line">set GOARCH=amd64</span><br><span class="line">set GOBIN=</span><br><span class="line">set GOCACHE=C:\Users\abel\AppData\Local\go-build</span><br><span class="line">set GOENV=C:\Users\abel\AppData\Roaming\go\env</span><br><span class="line">set GOEXE=.exe</span><br><span class="line">set GOFLAGS=</span><br><span class="line">set GOHOSTARCH=amd64</span><br><span class="line">set GOHOSTOS=windows</span><br><span class="line">set GONOPROXY=</span><br><span class="line">set GONOSUMDB=</span><br><span class="line">set GOOS=windows</span><br><span class="line">set GOPATH=C:\main\code\fanghaoli\server</span><br><span class="line">set GOPRIVATE=</span><br><span class="line">set GOPROXY=https://goproxy.cn</span><br><span class="line">set GOROOT=c:\go</span><br><span class="line">set GOSUMDB=sum.golang.org</span><br><span class="line">set GOTMPDIR=</span><br><span class="line">set GOTOOLDIR=c:\go\pkg\tool\windows_amd64</span><br><span class="line">set GCCGO=gccgo</span><br><span class="line">set AR=ar</span><br><span class="line">set CC=gcc</span><br><span class="line">set CXX=g++</span><br><span class="line">set CGO_ENABLED=1</span><br><span class="line">set GOMOD=</span><br><span class="line">set CGO_CFLAGS=-g -O2</span><br><span class="line">set CGO_CPPFLAGS=</span><br><span class="line">set CGO_CXXFLAGS=-g -O2</span><br><span class="line">set CGO_FFLAGS=-g -O2</span><br><span class="line">set CGO_LDFLAGS=-g -O2</span><br><span class="line">set PKG_CONFIG=pkg-config</span><br><span class="line">set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\abel\AppData\Local\Temp\go-build072770210=/tmp/go-build -gno-record-gcc-switches</span><br></pre></td></tr></table></figure>

<h6 id="go-clean"><a href="#go-clean" class="headerlink" title="go clean"></a>go clean</h6><p>清理工作目录，伤处编译和安装遗留的目标文件<br>| 参数 | 说明                      |<br>| —- | ————————- |<br>| -i   | 清理go install 安装的文件 |<br>| -r   | 递归清理所有依赖包        |<br>| -x   | 显示在执行的清理操作      |<br>| -n   | 仅显示清理命令，不执行    |</p>
<h6 id="编译"><a href="#编译" class="headerlink" title="编译"></a>编译</h6><p>如果喜欢使用gdb调试，一般需要使用 -gcflags “-N -l”阻止优化和内联，否则调试的时候会找不到调试信息。<br>当发布是，参数-ldflags “-w-s”会让连机器剔除掉符号表和调试信息，除了可以减少可执行文件的大小外，还能稍微增加反编译的难度。可以借助工具来对可执行文件进行减肥upx </p>
<h6 id="交叉编译"><a href="#交叉编译" class="headerlink" title="交叉编译"></a>交叉编译</h6><p>corss compile，就是在一个平台下出其他平台所需的可执行文件。只需要使用GOOS、GOARCH来调整环境变量指定平台和架构。<br>go env GOOS<br>使用go install命令为目标平台预编译好标准库，避免go build每次都完整编译。<br>交叉编译不支持cgo。</p>
<p>编写一个build_linux.bat文件</p>
<figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">set</span> GOARCH=amd64</span><br><span class="line"><span class="built_in">set</span> GOOS=linux</span><br><span class="line">go build</span><br></pre></td></tr></table></figure>

<p>跨平台编译需要下载一些库。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">https://github.com/golang/crypto.git</span><br><span class="line">https://github.com/golang/net.git</span><br><span class="line">https://github.com/golang/sys.git</span><br><span class="line">https://github.com/golang/tools.git</span><br></pre></td></tr></table></figure>

<p>解压缩之后放到这个目录下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$GOPATH/src/golang.org/x</span><br></pre></td></tr></table></figure>

<h6 id="条件编译"><a href="#条件编译" class="headerlink" title="条件编译"></a>条件编译</h6><p>编译器支持文件级别的条件编译。</p>
<p>1.将平台和架构信息添加到文件名尾部。</p>
<p>hello_darwin.go hello_linux.go 测试一下<br>GOOS=darwin.go build -x<br>将会只编译hello_darwin.go。<br>也可以对架构做条件<br>sys_arm64.go sys_darwin_3866.s sys_freebsd_amd64.s<br>文件名中可以使用GOOS,或者加上GOARCH。</p>
<p>2.使用build编译命令。</p>
<p>a.go</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// +build windows</span></span><br><span class="line">       &lt;---必须有空行</span><br><span class="line">       </span><br><span class="line"><span class="keyword">package</span> main</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">hello</span><span class="params">()</span></span> &#123;</span><br><span class="line">    <span class="built_in">println</span>(<span class="string">&quot;xxxx&quot;</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>b.go</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">// +build linux darwin</span><br><span class="line">// +build 386,/!cgo</span><br><span class="line"></span><br><span class="line">package main</span><br><span class="line">....</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>3.使用自定义tag指令。</p>
<p>// +build !release<br>// +build log</p>
<p>go build-tags “release log” &amp;&amp; ./xxxx</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://example.com/2020/11/03/2020/2020-11-03-go[0]-getstart/" data-id="ckrn3an6x000d20xwcne7d47m" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/golang/" rel="tag">golang</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-2020/2020-11-03-go[2]-数据类型" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2020/11/03/2020/2020-11-03-go%5B2%5D-%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/" class="article-date">
  <time datetime="2020-11-02T16:00:00.000Z" itemprop="datePublished">2020-11-03</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2020/11/03/2020/2020-11-03-go%5B2%5D-%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/">go[2]-数据结构</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>参考golang手册，记录数据类型相关资料；方便日后来回顾基础知识。</p>
<ul>
<li><a href="#%E5%9F%BA%E6%9C%AC%E6%95%B0%E6%8D%AE">基本数据</a><ul>
<li><a href="#%E5%B8%83%E5%B0%94">布尔</a></li>
<li><a href="#%E6%95%B4%E5%9E%8B%E6%B5%AE%E7%82%B9%E6%95%B0">整型/浮点数</a><ul>
<li><a href="#%E6%95%B4%E6%95%B0">整数</a></li>
<li><a href="#%E6%B5%AE%E7%82%B9%E7%B1%BB%E5%9E%8B">浮点类型</a></li>
</ul>
</li>
<li><a href="#string">String</a></li>
<li><a href="#const">const</a></li>
</ul>
</li>
<li><a href="#%E5%A4%8D%E5%90%88%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B">复合数据类型</a><ul>
<li><a href="#%E6%95%B0%E7%BB%84">数组</a></li>
<li><a href="#slice">slice</a></li>
<li><a href="#map">map</a></li>
<li><a href="#%E7%BB%93%E6%9E%84%E4%BD%93">结构体</a></li>
</ul>
</li>
</ul>
<h1 id="基本数据"><a href="#基本数据" class="headerlink" title="基本数据"></a>基本数据</h1><h2 id="布尔"><a href="#布尔" class="headerlink" title="布尔"></a>布尔</h2><p>布尔类型，表示真与假。true|false</p>
<h2 id="整型-浮点数"><a href="#整型-浮点数" class="headerlink" title="整型/浮点数"></a>整型/浮点数</h2><p>数值类型，分为整形和浮点类型，下面列举的是类型，以及读数的区间。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">uint8</span>       the set of all unsigned  <span class="number">8</span>-bit integers (<span class="number">0</span> to <span class="number">255</span>)</span><br><span class="line"><span class="keyword">uint16</span>      the set of all unsigned <span class="number">16</span>-bit integers (<span class="number">0</span> to <span class="number">65535</span>)</span><br><span class="line"><span class="keyword">uint32</span>      the set of all unsigned <span class="number">32</span>-bit integers (<span class="number">0</span> to <span class="number">4294967295</span>)</span><br><span class="line"><span class="keyword">uint64</span>      the set of all unsigned <span class="number">64</span>-bit integers (<span class="number">0</span> to <span class="number">18446744073709551615</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">int8</span>        the set of all signed  <span class="number">8</span>-bit integers (<span class="number">-128</span> to <span class="number">127</span>)</span><br><span class="line"><span class="keyword">int16</span>       the set of all signed <span class="number">16</span>-bit integers (<span class="number">-32768</span> to <span class="number">32767</span>)</span><br><span class="line"><span class="keyword">int32</span>       the set of all signed <span class="number">32</span>-bit integers (<span class="number">-2147483648</span> to <span class="number">2147483647</span>)</span><br><span class="line"><span class="keyword">int64</span>       the set of all signed <span class="number">64</span>-bit integers (<span class="number">-9223372036854775808</span> to <span class="number">9223372036854775807</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">byte</span>        alias <span class="keyword">for</span> <span class="keyword">uint8</span></span><br><span class="line"><span class="keyword">rune</span>        alias <span class="keyword">for</span> <span class="keyword">int32</span> </span><br></pre></td></tr></table></figure>

<p>整数类型按照字节数来分类，有8位、16位、32位、64位。每个数字的区间范围、内存空间都不一样。</p>
<p>int，uint会按照cpu字节大小最终是32位或者64位。Unicode.rune和int32等价，byte和uint8等价。</p>
<p>unsafe包里面提供的uintptr，不会规定内存的size，但是能容纳从c语言传递过来的内存指针。</p>
<h3 id="整数"><a href="#整数" class="headerlink" title="整数"></a>整数</h3><p>最高位使用了反码方式来表示。拿8位来举例子。他的取值范围是(-128 to 127)</p>
<p>-128= 二进制 1111 1111</p>
<p>127= 二进制 0111 1111</p>
<p>对有符号数字做位操作时，向右移将会自动补上符号位，向左移符号位不会受到影响。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">    <span class="keyword">var</span> a <span class="keyword">int8</span></span><br><span class="line">    a = <span class="number">-1</span></span><br><span class="line">    fmt.Printf(<span class="string">&quot;%08b\n&quot;</span>, a)</span><br><span class="line">    a = a &gt;&gt; <span class="number">2</span></span><br><span class="line">    fmt.Printf(<span class="string">&quot;%08b\n&quot;</span>, a)</span><br><span class="line">    a = a &lt;&lt; <span class="number">3</span></span><br><span class="line">    fmt.Printf(<span class="string">&quot;%08b\n&quot;</span>, a)</span><br><span class="line">    </span><br><span class="line">math.MinInt8</span><br></pre></td></tr></table></figure>

<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">-0000001</span><br><span class="line">-0000001</span><br><span class="line">-0001000</span><br><span class="line">``</span><br><span class="line"></span><br><span class="line">这个特性需要注意，一般在操作位的时候，我们都偏向使用无符号的数字来处理。</span><br><span class="line"></span><br><span class="line">在处理循环的时候，最好推荐使用有符号的变量来处理。防止程序出现问题。</span><br><span class="line"></span><br><span class="line"><span class="comment">### 无符号</span></span><br><span class="line"></span><br><span class="line">将会把全部的bit位当成数值来计算。在做位操作时，可以当成数组来理解。</span><br><span class="line"></span><br><span class="line">整数类型的运算优先级（行里面是级别相等，从上往下的列，级别是依次降低）：</span><br><span class="line"></span><br><span class="line">```go</span><br><span class="line">* / % &lt;&lt; &gt;&gt; &amp; &amp;^</span><br><span class="line">+ - | ^</span><br><span class="line">== != &lt; &lt;= &gt; &gt;=</span><br><span class="line">&amp;&amp;</span><br><span class="line">||</span><br></pre></td></tr></table></figure>

<h3 id="浮点类型"><a href="#浮点类型" class="headerlink" title="浮点类型"></a>浮点类型</h3><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">float32</span>     the set of all IEEE<span class="number">-754</span> <span class="number">32</span>-bit floating-point numbers</span><br><span class="line"><span class="keyword">float64</span>     the set of all IEEE<span class="number">-754</span> <span class="number">64</span>-bit floating-point numbers</span><br><span class="line"></span><br><span class="line"><span class="comment">// 复数</span></span><br><span class="line"><span class="keyword">complex64</span>   the set of all <span class="built_in">complex</span> numbers with <span class="keyword">float32</span> <span class="built_in">real</span> and imaginary parts</span><br><span class="line"><span class="keyword">complex128</span>  the set of all <span class="built_in">complex</span> numbers with <span class="keyword">float64</span> <span class="built_in">real</span> and imaginary parts</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>提供了 float32 float64 两种。IEEE 754标准。</p>
<p>所有极限值被定义在math包中。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">math.MaxFloat32</span><br></pre></td></tr></table></figure>

<p>float32 大约能理解成6个十进制的精度；float64能到15个十进制精度。</p>
<h2 id="String"><a href="#String" class="headerlink" title="String"></a>String</h2><p>string存储了一系列的bytes，string的字节数是就是字符串的长度，而且不可能为负数。当创建了字符串之后，将不会发生改变。可以使用内建函数len取得字符串的长度。可以通过下标方式取得字符串的数值。</p>
<p>可以通过操作，可以直接分离出内容</p>
<figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">str := <span class="string">&quot;0123456&quot;</span></span><br><span class="line">fmt.Println(str[<span class="number">0</span>:<span class="number">3</span>]) <span class="comment">// 012</span></span><br><span class="line">fmt.Println(str[<span class="number">3</span>:])  <span class="comment">// 3456</span></span><br><span class="line">fmt.Println(str[:<span class="number">3</span>])  <span class="comment">// 012</span></span><br></pre></td></tr></table></figure>

<p>不允许对字符串中间的内容做任何修改。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">.\main.<span class="keyword">go</span>:<span class="number">24</span>:<span class="number">9</span>: cannot assign to str[<span class="number">2</span>]</span><br></pre></td></tr></table></figure>

<p>转移方式：</p>
<p>\x11ff 十六进制<br>\o1188 八进制</p>
<p>原生字符串，一般用于制作正则表达式。使用反引号。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> GoUsage=<span class="string">`Go is a tool for managing xxx</span></span><br><span class="line"><span class="string">xxx... `</span></span><br></pre></td></tr></table></figure>

<p>unicode字符集，参考主页：<a target="_blank" rel="noopener" href="http://unicode.org/">http://unicode.org</a></p>
<p>golang使用的是utf32或者UCS-4，每个码点占用32bit。</p>
<p>utf-8</p>
<p>ascii部分是使用1个byte，常用字使用2或3个字符来表示。</p>
<p>解析的时候，读取高位来判断是采取几个字节（二进制）来加载。</p>
<p>高位为0，就是ascii，使用1个byte</p>
<p>0xxxxxxx</p>
<p>高位为110，需要使用2个byte</p>
<p>110xxxxx 10xxxxxx</p>
<p>高位为1110，需要使用3个byte</p>
<p>1110xxxx 10xxxxxx 10xxxxxx</p>
<p>高位为11110，需要使用4个byte</p>
<p>11110xxx 10xxxxxx 10xxxxxx 10xxxxxx</p>
<p>这样能完全兼容ascii码，而且能支持字符的压缩。</p>
<p>unicode/utf8包中，RuneCountInString能量出来utf8字符长度。</p>
<p>string相关的包 bytes,strings,strconv,unicode</p>
<p>strings包，主要提供查找、替换、比较、阶段、拆分和合并功能；</p>
<p>bytes包，用于处理[]byte的库，类似于strings。由于string是不能修改的，所以一般加工字符串的时候，都通过转换成[]byte来做处理。</p>
<p>string和[]byte的转换。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">bytes := []<span class="keyword">byte</span>(<span class="string">&quot;I am byte array !&quot;</span>)</span><br><span class="line">str := <span class="keyword">string</span>(bytes)</span><br></pre></td></tr></table></figure>

<p>strconv包，用于将布尔，整型，浮点与string之间做转换；<br>unicode包，用于处理utf8相关操作。</p>
<h2 id="const"><a href="#const" class="headerlink" title="const"></a>const</h2><p>测试实例</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> learngotest</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line">    <span class="string">&quot;fmt&quot;</span></span><br><span class="line">    <span class="string">&quot;testing&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> Priority <span class="keyword">int</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> (</span><br><span class="line">    LOG_EMERG Priority = <span class="literal">iota</span></span><br><span class="line">    LOG_ALERT</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">TestLogiota</span><span class="params">(t *testing.T)</span></span> &#123;</span><br><span class="line">    fmt.Println(LOG_EMERG)</span><br><span class="line">    fmt.Println(LOG_ALERT)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> (</span><br><span class="line">    mutexLocked = <span class="number">1</span> &lt;&lt; <span class="literal">iota</span> <span class="comment">// mutex is locked</span></span><br><span class="line">    mutexWoken</span><br><span class="line">    mutexStarving</span><br><span class="line">    mutexWaiterShift      = <span class="literal">iota</span></span><br><span class="line">    starvationThresholdNs = <span class="number">1e6</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">TestLockiota</span><span class="params">(t *testing.T)</span></span> &#123;</span><br><span class="line">    fmt.Println(mutexLocked)</span><br><span class="line">    fmt.Println(mutexWoken)</span><br><span class="line">    fmt.Println(mutexStarving)</span><br><span class="line">    fmt.Println(mutexWaiterShift) <span class="comment">// 3</span></span><br><span class="line">    fmt.Println(starvationThresholdNs)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> (</span><br><span class="line">    bit0, mask0 = <span class="number">1</span> &lt;&lt; <span class="literal">iota</span>, <span class="number">1</span>&lt;&lt;<span class="literal">iota</span> - <span class="number">1</span></span><br><span class="line">    bit1, mask1</span><br><span class="line">    _, _</span><br><span class="line">    bit3, mask3</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">TestBitiota</span><span class="params">(t *testing.T)</span></span> &#123;</span><br><span class="line">    fmt.Println(bit0, mask0) <span class="comment">// 1,0</span></span><br><span class="line">    fmt.Println(bit1, mask1) <span class="comment">// 2,1</span></span><br><span class="line">    fmt.Println(bit3, mask3) <span class="comment">// 8,7</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h1 id="复合数据类型"><a href="#复合数据类型" class="headerlink" title="复合数据类型"></a>复合数据类型</h1><h2 id="数组"><a href="#数组" class="headerlink" title="数组"></a>数组</h2><p>数组一般都是指定长度的某种类型 。由于长度无法变化，其实很少使用到。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a[<span class="number">3</span>] <span class="keyword">int</span></span><br><span class="line"><span class="keyword">var</span> b [<span class="number">3</span>]<span class="keyword">int</span> = [<span class="number">3</span>]<span class="keyword">int</span>&#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>&#125; <span class="comment">// 初始化</span></span><br><span class="line">c := [...]<span class="keyword">int</span>&#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>&#125;<span class="comment">//简略方式</span></span><br><span class="line">r := [...]<span class="keyword">int</span> &#123;<span class="number">99</span>:<span class="number">-1</span>&#125; <span class="comment">// 初始化了100个元素，100号位置写-1，其他全部都写0</span></span><br></pre></td></tr></table></figure>

<p>数组能直接做==的检测判断。</p>
<p>在调用函数的时候，将会赋值给函数的内部变量，如果参数使用了数组，将会存在内存拷贝。如果传递大的数组，将会有性能消耗。而且在修改数组内容时，也是在复制的数组中修改。如果想减少消耗，并且支持同步修改，还是需要使用数组指针方式来传递。</p>
<h2 id="slice"><a href="#slice" class="headerlink" title="slice"></a>slice</h2><p>切片是可变长的数组。每个元素都是相同类型。它包含了指针、长度和容量。指针是指向自己持有的slice的第一个元素，不一定是真实的数组中的第一个。长度，就是当前slice的长度。容积是全部长度。slice可以通过切片方法，分离出子串。其实本质上，他们还是指向同一个数组的。只是由于他们的指针位置不同，而体现出来不一样。</p>
<p>切片的方法<code>a[n:m]</code>将会取出<code>[n,m)</code>之间的元素出来，产生新的slice。<br>注意数字就是使用的下表，<code>从0开始</code>。<br>如果n没有填写，默认意思是0。<br>m没有填写，默认就是切片的长度。<br>常见用法：<br><code>a[:]</code>获取全部内容。<br><code>a[:0]</code>清理掉全部的成员=<code>[0,0)</code>；<br><code>s = s[:len(s)-1]</code>抓取最后一个元素；<br><code>s = s[len(s)-1:]</code>删除最后一个元素；</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">make</span>([]T,<span class="built_in">len</span>,[<span class="built_in">cap</span>])</span><br><span class="line"></span><br><span class="line"><span class="comment">// 测试</span></span><br></pre></td></tr></table></figure>

<p>append函数为slice追加内容。如果cap足够，那就直接添加到尾部，否则将重新创数组，将老数组copy进去，将新的内容添加到数组尾部。append都是返回一个新的数组出来，而不会去直接修改老数组。</p>
<p>slice类似这样的数据结构：</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> IntSlice <span class="keyword">struct</span> &#123;</span><br><span class="line">    ptr *<span class="keyword">int</span></span><br><span class="line">    <span class="built_in">len</span>,<span class="built_in">cap</span> <span class="keyword">int</span> </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>在使用 slice 的时候，需要注意底层存在一个数组。如果能复用，将会大大的提高运行效率。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> s []<span class="keyword">int</span></span><br><span class="line">    s = <span class="built_in">make</span>([]<span class="keyword">int</span>, <span class="number">0</span>)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="number">10</span>; i++ &#123;</span><br><span class="line">        s = <span class="built_in">append</span>(s, i)</span><br><span class="line">    &#125;</span><br><span class="line">    fmt.Printf(<span class="string">&quot;1 %#v\n&quot;</span>, s)</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 去掉头</span></span><br><span class="line">    s = s[<span class="number">1</span>:]</span><br><span class="line">    fmt.Println(s)</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 取出第一个</span></span><br><span class="line">    s = s[<span class="number">0</span>:<span class="number">1</span>]</span><br><span class="line">    fmt.Printf(<span class="string">&quot;2 %#v\n&quot;</span>, s)</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 清空</span></span><br><span class="line">    s = s[:<span class="number">0</span>]</span><br><span class="line">    fmt.Printf(<span class="string">&quot;3 %#v\n&quot;</span>, s)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="number">10</span>; i++ &#123;</span><br><span class="line">        s = <span class="built_in">append</span>(s, i)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 最后一个元素</span></span><br><span class="line">    s = s[<span class="built_in">len</span>(s)<span class="number">-1</span>:]</span><br><span class="line">    fmt.Printf(<span class="string">&quot;4 %#v\n&quot;</span>, s)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>需要做一次内存拷贝。如果不在乎顺序，可以直接将最后位置的元素，直接赋值掉指定位置的元素，删除slice最后的元素。</p>
<p>在stackoverflow里面的建议是直接使用连接两个拆分的slice，这样反而会比较高效。</p>
<p><a target="_blank" rel="noopener" href="https://stackoverflow.com/questions/37334119/how-to-delete-an-element-from-a-slice-in-golang">原文地址</a></p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">remove</span><span class="params">(slice []<span class="keyword">int</span>, s <span class="keyword">int</span>)</span> []<span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">append</span>(slice[:s], slice[s+<span class="number">1</span>:]...)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>slice在循环的时候，删除一个元素<code>golang slice delete while iterating</code></p>
<p>2018-11-13<a target="_blank" rel="noopener" href="https://studygolang.com/articles/16223">golang slice遍历删除-go语言中文网</a></p>
<p>2016-07-25<a target="_blank" rel="noopener" href="https://www.pauladamsmith.com/blog/2016/07/go-modify-slice-iteration.html">Modifying a Go slice in-place during iteration </a></p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> x = []<span class="keyword">int</span>&#123;<span class="number">90</span>, <span class="number">15</span>, <span class="number">81</span>, <span class="number">87</span>, <span class="number">47</span>, <span class="number">59</span>, <span class="number">81</span>, <span class="number">18</span>, <span class="number">25</span>, <span class="number">40</span>, <span class="number">56</span>, <span class="number">8</span>&#125;</span><br><span class="line"></span><br><span class="line">i := <span class="number">0</span></span><br><span class="line">l := <span class="built_in">len</span>(x)</span><br><span class="line"><span class="keyword">for</span> i &lt; l &#123;</span><br><span class="line">    <span class="keyword">if</span> x[i] % <span class="number">2</span> != <span class="number">0</span> &#123;</span><br><span class="line">        x = <span class="built_in">append</span>(x[:i], x[i+<span class="number">1</span>:]...)</span><br><span class="line">        l--</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        i++</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">x = x[:i]</span><br><span class="line"></span><br><span class="line">fmt.Println(x)</span><br><span class="line"><span class="comment">// [90 18 40 56 8]</span></span><br></pre></td></tr></table></figure>

<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="string">&quot;fmt&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/*slice 遍历删除示例*/</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">    <span class="comment">//定义一个数字切片</span></span><br><span class="line">    ageList := []<span class="keyword">int</span>&#123;<span class="number">1</span>, <span class="number">3</span>, <span class="number">7</span>, <span class="number">7</span>, <span class="number">8</span>, <span class="number">2</span>, <span class="number">5</span>&#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//遍历删除6以下的</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="built_in">len</span>(ageList); &#123;</span><br><span class="line">        <span class="keyword">if</span> ageList[i] &lt; <span class="number">6</span> &#123;</span><br><span class="line">            ageList = <span class="built_in">append</span>(ageList[:i], ageList[i+<span class="number">1</span>:]...)</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            i++</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    fmt.Printf(<span class="string">&quot;after del:%v&quot;</span>, ageList)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>输出 after del:[7 7 8]</p>
<p><a target="_blank" rel="noopener" href="https://stackoverflow.com/questions/20545743/how-to-remove-items-from-a-slice-while-ranging-over-it">stackoverflow中的例子</a></p>
<p>获取高赞的处理方法，第一遍是将全部有用节点排列到<code>&lt;i</code>的数组里面，<code>[i,j)</code>之间的内存都做一次强制的设置成空。<code>s = s[:i]</code>就是将slice区域重置。</p>
<figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">i := <span class="number">0</span> <span class="comment">// output index</span></span><br><span class="line"><span class="keyword">for</span> _, x := <span class="keyword">range</span> s &#123;</span><br><span class="line">    <span class="keyword">if</span> isValid(x) &#123;</span><br><span class="line">        <span class="comment">// copy and increment index</span></span><br><span class="line">        s[i] = x</span><br><span class="line">        i++</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// Prevent memory leak by erasing truncated values </span></span><br><span class="line"><span class="comment">// (not needed if values don&#x27;t contain pointers, directly or indirectly)</span></span><br><span class="line"><span class="keyword">for</span> j := i; j &lt; <span class="built_in">len</span>(s); j++ &#123;</span><br><span class="line">    s[j] = <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line">s = s[:i]</span><br></pre></td></tr></table></figure>

<p>注意，这将在底层数组中的索引i之后保留旧值，因此如果值是或包含指针，这将泄漏内存，直到片本身被垃圾收集。您可以通过将所有值设置为nil或从i到切片结束的零值来解决此问题，然后再截断切片。这个警告适用于说第二步骤需要小心。</p>
<h2 id="map"><a href="#map" class="headerlink" title="map"></a>map</h2><p>key/value方式无序的集合。golang中的map其实就是哈希表。其中key的类型需要支持==比较运算符。浮点型最好不好当成key。</p>
<p>创建map的方法</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">ages :=<span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">string</span>]<span class="keyword">int</span>)</span><br><span class="line">ages := <span class="keyword">map</span>[<span class="keyword">string</span>]<span class="keyword">int</span> &#123;</span><br><span class="line">    <span class="string">&quot;alice&quot;</span> : <span class="number">31</span>,</span><br><span class="line">    <span class="string">&quot;Charlie&quot;</span> : <span class="number">34</span>,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>map的元素可以通过key下标来访问</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ages[<span class="string">&quot;alice&quot;</span>]=<span class="number">32</span></span><br><span class="line">fmt.Println(ages[<span class="string">&quot;alice&quot;</span>])</span><br></pre></td></tr></table></figure>

<p>通过delete对map中的元素删除，即使不存在也能删除。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">delete</span>(ages,<span class="string">&quot;alice&quot;</span>)</span><br></pre></td></tr></table></figure>

<p>在循环map的时候，删除keys是否安全。<code>Is it safe to remove selected keys from map within a range loop?</code></p>
<p><a target="_blank" rel="noopener" href="https://stackoverflow.com/questions/23229975/is-it-safe-to-remove-selected-keys-from-map-within-a-range-loop">stackoverflow实例map在遍历的时候删除</a></p>
<p><a target="_blank" rel="noopener" href="https://golang.org/doc/effective_go#for">effective_go</a></p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> key := <span class="keyword">range</span> m &#123;</span><br><span class="line">    <span class="keyword">if</span> key.expired() &#123;</span><br><span class="line">        <span class="built_in">delete</span>(m, key)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>也能直接对不存在的元素直接做操作</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ages[<span class="string">&quot;bob&quot;</span>] = ages[<span class="string">&quot;bob&quot;</span>]+<span class="number">1</span></span><br></pre></td></tr></table></figure>

<p>系统会自动初始化key为bob的元素并且返回0</p>
<p>map中的元素不是变量，所以无法取得地址。原因也是由于随着元素的删减，可能内存空间有放大，或者缩小。所以取得的内存地址可能失效。</p>
<p>循环方式是</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> name,age := <span class="keyword">range</span> ages &#123;</span><br><span class="line">    fmt.Printf(<span class="string">&quot;%s\t%d\n&quot;</span>,name,age)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>由于是hash所以遍历的顺序是不固定的。map变量定义出来之后都是nil值。可以通过make语句来创建初始化。</p>
<p>如需要检查一个元素是否有初始化，可以通过</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">age, ok := ages[<span class="string">&quot;bob&quot;</span>]</span><br><span class="line"><span class="keyword">if</span> !ok &#123;</span><br><span class="line">  <span class="comment">// 不存在元素。</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>map容器不能直接做比较操作。</p>
<p>go语言没有提供set类型，可以使用map来代替。</p>
<h2 id="结构体"><a href="#结构体" class="headerlink" title="结构体"></a>结构体</h2><p>结构体里面可以定义0-n个成员。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> T <span class="keyword">struct</span> &#123;</span><br><span class="line">    a,b <span class="keyword">int</span></span><br><span class="line">&#125;</span><br><span class="line">val := &amp;T&#123;a:<span class="number">1</span>,b:<span class="number">2</span>&#125;</span><br></pre></td></tr></table></figure>

<p>如果函数需要修改结构体内容，出于对效率的考虑，一般都是使用结构体的引用作为参数来传递。</p>
<p>结构体的嵌套</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> Point <span class="keyword">struct</span> &#123;</span><br><span class="line">    X,Y <span class="keyword">int</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">type</span> Circle <span class="keyword">struct</span> &#123;</span><br><span class="line">    Center Point</span><br><span class="line">    Radius <span class="keyword">int</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">type</span> Wheel <span class="keyword">struct</span> &#123;</span><br><span class="line">    Circle Circle</span><br><span class="line">    Spokes <span class="keyword">int</span>    <span class="comment">// 辐条</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> w Wheel</span><br><span class="line">w.Circle.Center.X = <span class="number">8</span></span><br></pre></td></tr></table></figure>

<p>go语言中能再struct中定义匿名的成员，这样就直接将其他的struct直接嵌入到了自己的结构体</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> Circle <span class="keyword">struct</span> &#123;</span><br><span class="line">    Point</span><br><span class="line">    Radius <span class="keyword">int</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">type</span> Wheel <span class="keyword">struct</span> &#123;</span><br><span class="line">    Circle</span><br><span class="line">    Spokes <span class="keyword">int</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> w Wheel</span><br><span class="line">w.X = <span class="number">9</span></span><br></pre></td></tr></table></figure>

<p>struct可以通过</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">fmt.Printf(<span class="string">&quot;%#v\n&quot;</span>,w)</span><br></pre></td></tr></table></figure>

<p>输出信息。</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://example.com/2020/11/03/2020/2020-11-03-go[2]-%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/" data-id="ckrn3an6y000f20xwfuyu793z" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/golang/" rel="tag">golang</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/type/" rel="tag">type</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-2019/2019-03-04-lua-protobuf" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/03/04/2019/2019-03-04-lua-protobuf/" class="article-date">
  <time datetime="2019-03-03T16:00:00.000Z" itemprop="datePublished">2019-03-04</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/03/04/2019/2019-03-04-lua-protobuf/">lua使用protobuf</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>protobuf是比较好的一种序列化的工具，这里使用lua来试用一下protobuf。文章内容是通过网络收集的知识</p>
<p><a target="_blank" rel="noopener" href="https://github.com/cloudwu/pbc">pbc下载地址</a><br><a target="_blank" rel="noopener" href="https://github.com/protocolbuffers/protobuf">protobuf下载地址</a></p>
<p>protoc工具支持将protobuf 3.5.1导出c语言用。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ protoc -I=&#123;proto_path&#125; -o&#123;output_path&#125;/&#123;filename&#125;.pb &#123;filename&#125;.proto</span><br></pre></td></tr></table></figure>

<p>lua中使用：</p>
<figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">module</span>(<span class="string">&quot;test_protobuf&quot;</span>,<span class="built_in">package</span>.<span class="built_in">seeall</span>)</span><br><span class="line">protobuf  = <span class="built_in">require</span> <span class="string">&quot;protobuf&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">init_protobuf</span><span class="params">()</span></span></span><br><span class="line">    <span class="keyword">local</span> addr = <span class="built_in">io</span>.<span class="built_in">open</span>(<span class="string">&quot;./proto/mx_svr.pb&quot;</span>,<span class="string">&quot;rb&quot;</span>)</span><br><span class="line">    <span class="keyword">local</span> buffer = addr:<span class="built_in">read</span> <span class="string">&quot;*a&quot;</span></span><br><span class="line">    addr:<span class="built_in">close</span>()</span><br><span class="line">    protobuf.register(buffer)</span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">decode_data</span><span class="params">(_node)</span></span></span><br><span class="line">    <span class="keyword">local</span> msg, info = protobuf.decode(<span class="string">&quot;mx_svr.W2GPack&quot;</span>, _node.data, #_node.data)</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">type</span>(msg) == <span class="string">&quot;boolean&quot;</span> <span class="keyword">then</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;decode_data protobuf.decode failed, info: &quot;</span>, info)</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>, msg</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">return</span> <span class="literal">true</span>, msg</span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">encode_data</span><span class="params">(_tbl)</span></span></span><br><span class="line">    <span class="keyword">local</span> buffer = protobuf.encode(<span class="string">&quot;mx_svr.W2GPack&quot;</span>, _tbl)</span><br><span class="line">    <span class="keyword">return</span> buffer</span><br><span class="line"></span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://example.com/2019/03/04/2019/2019-03-04-lua-protobuf/" data-id="ckrn3an6s000120xweppm8r54" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/protobuf/" rel="tag">protobuf</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-2018/2018-11-30-golang-protobuf" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2018/11/30/2018/2018-11-30-golang-protobuf/" class="article-date">
  <time datetime="2018-11-29T16:00:00.000Z" itemprop="datePublished">2018-11-30</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2018/11/30/2018/2018-11-30-golang-protobuf/">golang protobuf 尝试</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>protobuf是比较好的一种序列化的工具，这里使用golang来试用一下protobuf</p>
<p> <a target="_blank" rel="noopener" href="https://github.com/golang/protobuf">protobuf模块</a>  <a target="_blank" rel="noopener" href="https://developers.google.com/protocol-buffers/docs/gotutorial">参考文档</a> </p>
<h1 id="准备工具"><a href="#准备工具" class="headerlink" title="准备工具"></a>准备工具</h1><p>安装命令</p>
<p><img src="https://swordhell.github.io/img/pic/20181201080640-install-go-protocol1.png"></p>
<p>安装效果</p>
<p><img src="https://swordhell.github.io/img/pic/20181201080640-install-go-protocol2.png"></p>
<p>环境变量配置</p>
<p><img src="https://swordhell.github.io/img/pic/20181201080640-install-go-protocol3.png"></p>
<h1 id="定义protobuf"><a href="#定义protobuf" class="headerlink" title="定义protobuf"></a>定义protobuf</h1><figure class="highlight protobuf"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">syntax = <span class="string">&quot;proto3&quot;</span>;</span><br><span class="line"><span class="keyword">package</span> example;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">message</span> <span class="title">Person</span> </span>&#123;</span><br><span class="line">  <span class="built_in">string</span> name = <span class="number">1</span>;</span><br><span class="line">  <span class="built_in">int32</span> id = <span class="number">2</span>;  <span class="comment">// Unique ID number for this person.</span></span><br><span class="line">  <span class="built_in">string</span> email = <span class="number">3</span>;</span><br><span class="line"></span><br><span class="line">  <span class="class"><span class="keyword">enum</span> <span class="title">PhoneType</span> </span>&#123;</span><br><span class="line">    MOBILE = <span class="number">0</span>;</span><br><span class="line">    HOME = <span class="number">1</span>;</span><br><span class="line">    WORK = <span class="number">2</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="class"><span class="keyword">message</span> <span class="title">PhoneNumber</span> </span>&#123;</span><br><span class="line">    <span class="built_in">string</span> number = <span class="number">1</span>;</span><br><span class="line">    PhoneType type = <span class="number">2</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">repeated</span> PhoneNumber phones = <span class="number">4</span>;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// Our address book file is just one of these.</span></span><br><span class="line"><span class="class"><span class="keyword">message</span> <span class="title">AddressBook</span> </span>&#123;</span><br><span class="line">  <span class="keyword">repeated</span> Person people = <span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h1 id="生成go文件"><a href="#生成go文件" class="headerlink" title="生成go文件"></a>生成go文件</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">protoc.exe -I=D:/gopath/src/IDL --go_out=./ D:/gopath/src/IDL/addressbook.proto</span><br></pre></td></tr></table></figure>

<h1 id="编写序列化、反序列化代码"><a href="#编写序列化、反序列化代码" class="headerlink" title="编写序列化、反序列化代码"></a>编写序列化、反序列化代码</h1><p><a target="_blank" rel="noopener" href="https://github.com/protocolbuffers/protobuf/blob/master/examples/list_people_test.go">参考代码</a></p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line">	<span class="string">&quot;fmt&quot;</span></span><br><span class="line"></span><br><span class="line">	<span class="string">&quot;github.com/golang/protobuf/proto&quot;</span></span><br><span class="line"></span><br><span class="line">	pb <span class="string">&quot;octopus.com/test/test_protobuf/example&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line"></span><br><span class="line">	p := &amp;pb.Person&#123;</span><br><span class="line">		Id:    <span class="number">1234</span>,</span><br><span class="line">		Name:  <span class="string">&quot;John Doe&quot;</span>,</span><br><span class="line">		Email: <span class="string">&quot;jdoe@example.com&quot;</span>,</span><br><span class="line">		Phones: []*pb.Person_PhoneNumber&#123;</span><br><span class="line">			&#123;Number: <span class="string">&quot;555-4321&quot;</span>, Type: pb.Person_HOME&#125;,</span><br><span class="line">		&#125;,</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	fmt.Println(p)</span><br><span class="line"></span><br><span class="line">	out, err := proto.Marshal(p)</span><br><span class="line">	<span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">		fmt.Println(err)</span><br><span class="line">		<span class="keyword">return</span></span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	fmt.Println(out)</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>输出：</p>
<figure class="highlight console"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">name:&quot;John Doe&quot; id:1234 email:&quot;jdoe@example.com&quot; phones:&lt;number:&quot;555-4321&quot; type:HOME &gt; </span><br><span class="line">[10 8 74 111 104 110 32 68 111 101 16 210 9 26 16 106 100 111 101 64 101 120 97 109 112 108 101 46 99 111 109 34 12 10 8 53 53 53 45 52 51 50 49 16 1]</span><br></pre></td></tr></table></figure>


      
    </div>
    <footer class="article-footer">
      <a data-url="http://example.com/2018/11/30/2018/2018-11-30-golang-protobuf/" data-id="ckrn3an6u000520xwd1ojdie0" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/golang/" rel="tag">golang</a></li></ul>

    </footer>
  </div>
  
</article>


  


  <nav id="page-nav">
    
    <a class="extend prev" rel="prev" href="/page/3/">&amp;laquo; Prev</a><a class="page-number" href="/">1</a><a class="page-number" href="/page/2/">2</a><a class="page-number" href="/page/3/">3</a><span class="page-number current">4</span><a class="page-number" href="/page/5/">5</a><a class="extend next" rel="next" href="/page/5/">Next &amp;raquo;</a>
  </nav>

</section>
        
          <aside id="sidebar">
  
    

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/tags/3D/" rel="tag">3D</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/AI/" rel="tag">AI</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/C/" rel="tag">C++</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Game/" rel="tag">Game</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Go/" rel="tag">Go</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Linux/" rel="tag">Linux</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Math/" rel="tag">Math</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Server/" rel="tag">Server</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Unreal-Engine4/" rel="tag">Unreal Engine4</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/git/" rel="tag">git</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/golang/" rel="tag">golang</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/guitar/" rel="tag">guitar</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/node-js/" rel="tag">node.js</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/protobuf/" rel="tag">protobuf</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/python/" rel="tag">python</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/recast/" rel="tag">recast</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/redis/" rel="tag">redis</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/type/" rel="tag">type</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/vscode/" rel="tag">vscode</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E8%BF%90%E7%BB%B4/" rel="tag">运维</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/tags/3D/" style="font-size: 10px;">3D</a> <a href="/tags/AI/" style="font-size: 11.67px;">AI</a> <a href="/tags/C/" style="font-size: 15px;">C++</a> <a href="/tags/Game/" style="font-size: 18.33px;">Game</a> <a href="/tags/Go/" style="font-size: 13.33px;">Go</a> <a href="/tags/Linux/" style="font-size: 13.33px;">Linux</a> <a href="/tags/Math/" style="font-size: 11.67px;">Math</a> <a href="/tags/Server/" style="font-size: 16.67px;">Server</a> <a href="/tags/Unreal-Engine4/" style="font-size: 10px;">Unreal Engine4</a> <a href="/tags/git/" style="font-size: 10px;">git</a> <a href="/tags/golang/" style="font-size: 20px;">golang</a> <a href="/tags/guitar/" style="font-size: 10px;">guitar</a> <a href="/tags/node-js/" style="font-size: 10px;">node.js</a> <a href="/tags/protobuf/" style="font-size: 10px;">protobuf</a> <a href="/tags/python/" style="font-size: 10px;">python</a> <a href="/tags/recast/" style="font-size: 11.67px;">recast</a> <a href="/tags/redis/" style="font-size: 10px;">redis</a> <a href="/tags/type/" style="font-size: 10px;">type</a> <a href="/tags/vscode/" style="font-size: 10px;">vscode</a> <a href="/tags/%E8%BF%90%E7%BB%B4/" style="font-size: 16.67px;">运维</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/07/">July 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/06/">June 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/04/">April 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/03/">March 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/01/">January 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/12/">December 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/11/">November 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/03/">March 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/11/">November 2018</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2021/07/19/2021/2021-07-19-etcd-learn/">go-etcd阅读笔记</a>
          </li>
        
          <li>
            <a href="/2021/07/19/2021/2021-07-19-socketop-learn/">REUSEPORT-REUSEADDR-学习</a>
          </li>
        
          <li>
            <a href="/2021/06/22/2021/2021-06-22-go-ethereum-learn/">go-ethereum阅读笔记</a>
          </li>
        
          <li>
            <a href="/2021/06/21/2021/2021-06-21-server%E6%B5%8B%E8%AF%95%E5%B7%A5%E5%85%B7/">server测试工具</a>
          </li>
        
          <li>
            <a href="/2021/06/09/2021/2021-06-09-pprof-doc/">go-pprof</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2021 Abel Sean<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>


  
<link rel="stylesheet" href="/fancybox/jquery.fancybox.css">

  
<script src="/fancybox/jquery.fancybox.pack.js"></script>




<script src="/js/script.js"></script>




  </div>
</body>
</html>